Exam Area: Area 1 – Product Knowledge (15%) Reference: https://docs.developers.optimizely.com/content-management-system/docs/on-page-editing
On-page editing (also called in-context editing) allows editors to edit content directly on the rendered page inside the CMS Edit View — without opening a separate form.
When an editor is in On-page Edit mode:
To make a property editable on the page, use Html.PropertyFor() in the Razor view:
@* String property — renders as inline text editor in Edit mode *@
@Html.PropertyFor(m => m.CurrentPage.Heading)
@* XhtmlString — renders as rich-text (TinyMCE) in Edit mode *@
@Html.PropertyFor(m => m.CurrentPage.MainBody)
@* ContentArea — renders as drag-and-drop zone in Edit mode *@
@Html.PropertyFor(m => m.CurrentPage.MainContentArea)
@* ContentReference (image) — renders as image picker in Edit mode *@
@Html.PropertyFor(m => m.CurrentPage.HeroImage)
@* Equivalent Tag Helper syntax *@
<epi-property name="Heading" model="@Model.CurrentPage"></epi-property>
Important: Properties rendered with direct Razor output (
@Model.CurrentPage.Heading) do NOT support on-page editing. You must use@Html.PropertyFor()or the tag helper.
public enum ContextMode
{
Default = 0, // Normal visitor view
Edit = 1, // Inside CMS Edit View (OPE enabled)
Preview = 2, // CMS Preview (read-only)
Undefined = 3 // Not yet determined
}
// Inject to determine context
public class ArticleController : PageController<ArticlePage>
{
private readonly IContextModeResolver _contextMode;
public ArticleController(IContextModeResolver contextMode)
{
_contextMode = contextMode;
}
public ActionResult Index(ArticlePage currentPage)
{
var isEditing = _contextMode.CurrentMode == ContextMode.Edit;
var viewModel = new ArticleViewModel(currentPage)
{
IsEditing = isEditing
};
return View(viewModel);
}
}
@* Check context mode in a view *@
@inject EPiServer.Web.IContextModeResolver ContextModeResolver
@if (ContextModeResolver.CurrentMode != ContextMode.Default)
{
<div class="editorial-hint">
📝 Editing mode active — visitors do not see this
</div>
}
DisplayChannels let you render different HTML for different channels (desktop, mobile, print) or for Edit Mode. They are set in the request context.
// Register a custom display channel
[ServiceConfiguration(typeof(IDisplayChannel))]
public class MobileDisplayChannel : IDisplayChannel
{
public string ChannelName => "mobile";
public bool IsActive(HttpContextBase context)
{
// Check user-agent for mobile
return context.Request.IsMobileDevice;
}
}
@* Use DisplayChannel in a view *@
@inject EPiServer.Web.Hosting.IDisplayChannelService DisplayChannelService
@if (DisplayChannelService.IsChannelActive("mobile"))
{
<img src="/images/hero-mobile.jpg" />
}
else
{
<img src="/images/hero-desktop.jpg" />
}
Use UIHint to control how a property is rendered in the Edit UI:
// Render as a single-line text (even if property is XhtmlString)
[UIHint(UIHint.Textarea)]
public virtual string ShortDescription { get; set; }
// Image picker (inline thumbnail in OPE)
[UIHint(UIHint.Image)]
public virtual ContentReference HeroImage { get; set; }
// Video picker
[UIHint(UIHint.Video)]
public virtual ContentReference HeroVideo { get; set; }
// Allow specific block types in ContentArea
[AllowedTypes(
AllowedTypes = new[] { typeof(TeaserBlock), typeof(HeroBlock) },
RestrictedTypes = new[] { typeof(FormBlock) })]
public virtual ContentArea MainContentArea { get; set; }
@* Renders as drag-drop zone in Edit mode *@
@Html.PropertyFor(m => m.CurrentPage.MainContentArea)
@* Custom rendering with tag — each block wrapped in a div *@
@Html.PropertyFor(m => m.CurrentPage.MainContentArea, new
{
Tag = RenderingTags.Main,
CssClass = "main-content"
})
These property types cannot be edited on-page — they always use the All Properties form:
| Feature | Edit (ContextMode.Edit) | Preview (ContextMode.Preview) |
|---|---|---|
| OPE overlays shown | ✅ Yes | ❌ No |
| Editing possible | ✅ Yes | ❌ No (read-only) |
| Draft content visible | ✅ Yes | ✅ Yes |
| Publish toolbar shown | ✅ Yes | ❌ No |
DateTime property be edited on-page? (No — it requires the All Properties form)[AllowedTypes] on a ContentArea do? (Restricts which block types can be dropped in)