@nele.debrouwer
Hm, I'm guessing you are accessing the administration through one of the website channel domains?
If so, don't do this ð.
The administration is not a website channel. It should be accessed by a non-channel domain that is only used for the administration.
If you look at the Community Portal project you can see we have this separation in the local environment. The Community Portal is deployed to SaaS which enforces this separation.
Here's an example of the system domains in the SaaS environment (which are used to access the administration UI):

You can also see the error that is displayed if you try to access a website channel from the system (administration) domain:

Update #1
I just realized the use-case I was testing for this solution didn't match your use-case. So, in addition to my example solutions and my guidance above (which still applies), I also acknowledge we have a gap in the product right now.
You can't use IWebsiteChannelContext
or IPageBuilderDataContextRetriever
in Page Builder UI Form Components or related types (visibility conditions, custom options providers).
We have some internal services to access this context, but they aren't available for you to use. We'll look at exposing this information in the future.
In the meantime, here's a ... "workaround" that you can use ð:
public interface IPageBuilderUtilityContextRetriever
{
Task<PageBuilderUtilityContext> Retrieve();
}
public record PageBuilderUtilityContext(
string WebsiteChannelName,
int WebsiteChannelID,
IWebPageFieldsSource Webpage);
public class PageBuilderUtilityContextRetriever(
IHttpContextAccessor contextAccessor,
IInfoProvider<ChannelInfo> channelInfoProvider,
IContentQueryExecutor queryExecutor)
: IPageBuilderUtilityContextRetriever
{
private readonly IHttpContextAccessor contextAccessor = contextAccessor;
private readonly IInfoProvider<ChannelInfo> channelInfoProvider = channelInfoProvider;
private readonly IContentQueryExecutor queryExecutor = queryExecutor;
private PageBuilderUtilityContext? context = null;
public async Task<PageBuilderUtilityContext> Retrieve()
{
if (context is not null)
{
return context;
}
int websiteChannelID = 0;
int webPageID = 0;
var httpContext = contextAccessor.HttpContext;
string path = httpContext.Request.Form["path"].FirstOrDefault() ?? "";
string pattern = @"webpages-(\d+)/([^_/]+)_(\d+)";
var match = Regex.Match(path, pattern);
if (match.Success)
{
websiteChannelID = int.TryParse(match.Groups[1].Value, out int channelID) ? channelID : 0;
webPageID = int.TryParse(match.Groups[3].Value, out int pageID) ? pageID : 0;
}
var channels = await channelInfoProvider.Get()
.Source(s => s.Join<WebsiteChannelInfo>(nameof(ChannelInfo.ChannelID), nameof(WebsiteChannelInfo.WebsiteChannelChannelID)))
.Where(w => w.WhereEquals(nameof(WebsiteChannelInfo.WebsiteChannelID), websiteChannelID))
.Columns(nameof(ChannelInfo.ChannelName))
.GetEnumerableTypedResultAsync();
string websiteChannelName = channels
.Select(s => s.ChannelName)
.FirstOrDefault() ?? "";
var query = new ContentItemQueryBuilder()
.ForContentTypes(q => q.ForWebsite([webPageID], false));
var pages = await queryExecutor.GetMappedWebPageResult<IWebPageFieldsSource>(query);
var webPage = pages.FirstOrDefault();
context = new(websiteChannelName, websiteChannelID, webPage);
return context;
}
}
Register this service with DI:
services.AddScoped<
IPageBuilderUtilityContextRetriever,
PageBuilderUtilityContextRetriever>();
And then inject into your visibility condition class constructor.
You'll probably want to add better guards in the Retrieve()
method or maybe convert it to TryRetrieve()
in case the context can't be retrieved.