Customize for edit view
Describes how to configure edit view for displaying content in the Optimizely Content Delivery API.
Return draft and expired content
From Optimizely Content Delivery API 2.6.0, draft and expired content is not returned by Content Delivery API by default. If you try to retrieve a draft or expired content, you will probably get a 404 Not Found. This is convenient when you use Content Delivery API to build a Single-Page Application (SPA) for view mode and when the client should not care about the draft or expired page – as in a standard Alloy site. However, in edit view, you may want to get content, including the draft and expired content. Content Delivery API lets you customize its ContentLoaderService to achieve this.
First, create a class CustomContentLoaderService
derived from ContentLoaderService
; and within this class, override the function ShouldContentBeExposed
. Finally, register a class as the default service for ContentLoaderService
in Startup.cs
.
Example:
services.AddTransient<ContentLoaderService, CustomContentLoaderService>();
public class CustomContentLoaderService: ContentLoaderService {
private readonly EPiServer.Web.IContextModeResolver _contentModeResolver;
public CustomContentLoaderService(
IContentLoader contentLoader,
IPermanentLinkMapper permanentLinkMapper,
IContentProviderManager providerManager,
IPublishedStateAssessor publishedStateAssessor,
EPiServer.Web.IContextModeResolver contentModeResolver
): base(contentLoader, permanentLinkMapper, providerManager, publishedStateAssessor) {
_contentModeResolver = contentModeResolver;
}
protected override bool ShouldContentBeExposed(IContent content) {
//In EditMode, unpublished or expired content is still returned
if (_contentModeResolver.CurrentMode == ContextMode.Edit) {
return true;
}
return base.ShouldContentBeExposed(content);
}
}
 Resolve URL based on context
When you fetch content from Content Delivery API, there is a URL property that contains the CMS-friendly URL of the requested content (for example, /en/artists/
). However, the content URL is different in edit view. If you want to get the right URL in edit view, like on the Alloy site, you should override the UrlResolverService
to resolve the correct URL of the content based on the current request context.
- Create a class called
CustomUrlResolverService
that derived fromUrlResolverService
, and override theResolveUrl
method. - Register this class as the default service for
UrlResolverService
inInitializableModule
.
Example:
public void ConfigureContainer(ServiceConfigurationContext context) {
context.Services.AddSingleton<UrlResolverService, CustomUrlResolverService>();
}
public class CustomUrlResolverService: UrlResolverService {
private readonly ServiceAccessor<HttpContextBase> _httpContextAccessor;
public CustomUrlResolverService(UrlResolver urlResolver,
ContentApiConfiguration contentApiConfiguration,
ServiceAccessor<HttpContextBase> httpContextAccessor): base(urlResolver, contentApiConfiguration) {
_httpContextAccessor = httpContextAccessor;
}
public override string ResolveUrl(ContentReference contentLink, string language) {
return _urlResolver.GetUrl(contentLink, language, new VirtualPathArguments {
ContextMode = GetContextMode()
});
}
private ContextMode GetContextMode() {
var httpCtx = _httpContextAccessor();
if (httpCtx == null || httpCtx.Request == null || httpCtx.Request.QueryString[PageEditing.EpiEditMode] == null) {
return ContextMode.Default;
}
if (bool.TryParse(httpCtx.Request.QueryString[PageEditing.EpiEditMode], out bool editMode)) {
return editMode ? ContextMode.Edit : ContextMode.Preview;
}
return ContextMode.Undefined;
}
}
Example:
 Impersonate visitor group
Content Delivery API default filters content based on the user's visitor group. You may want to send a visitor group ID in request parameters and use this ID to filter content. A use case is, for example, the preview in CMS. You can change the visitor group ID in the drop-down menu, and the page is displayed as viewed by the selected visitor group.
When using Content Delivery API to build a SPA edit view, you can add a custom filter to make Content Delivery API filter content based on the visitor group retrieved from the request context.
- First, create a class called
ImpersonateVGFilter
that implementIContentFilter
. - Register the
ImpersonateVGFilter
in your service container.
public class ImpersonateVGFilter: IContentFilter {
private readonly IHttpContextAccessor _httpContextAccessor;
public ImpersonateVGFilter(IHttpContextAccessor httpContextAccessor) {
_httpContextAccessor = httpContextAccessor ??
throw new ArgumentNullException(nameof(httpContextAccessor));
}
public Type HandledContentModel => typeof (IContent);
public void Filter(IContent content, ConverterContext converterContext) {
var visitorGroupId = _httpContextAccessor.HttpContext.Request.Query[VisitorGroupRole.VisitorGroupKeyByID];
if (!string.IsNullOrEmpty(visitorGroupId)) {
// setup impersonate visitor group
_httpContextAccessor.HttpContext.SetupVisitorGroupImpersonation(content, AccessLevel.Read);
}
}
}
services.TryAddEnumerable(ServiceDescriptor.Singleton<IContentFilter, ImpersonateVGFilter>());
Updated 6 months ago