📚 Product Knowledge
On Page Edit
📖 Docs

On-page Editing - Optimizely CMS 12

Exam Area: Area 1 – Product Knowledge (15%) Reference: https://docs.developers.optimizely.com/content-management-system/docs/on-page-editing


1. What is On-page Editing (OPE)?

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:


2. Enabling On-page Editing in Templates

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.


3. ContextMode Enum

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
}

4. IContextModeResolver

// 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>
}

5. DisplayChannel

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" />
}

6. PropertyFor Rendering Hints

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; }

7. ContentArea Drag-and-Drop

// 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"
})

8. Inline Editing Not Available For

These property types cannot be edited on-page — they always use the All Properties form:


9. Preview Mode vs Edit Mode

FeatureEdit (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

Review Questions

  1. What helper method enables on-page editing in a Razor view? (@Html.PropertyFor())
  2. Which ContextMode is active during on-page editing? (ContextMode.Edit)
  3. What interface is used to check the current context mode? (IContextModeResolver)
  4. Can a DateTime property be edited on-page? (No — it requires the All Properties form)
  5. What does [AllowedTypes] on a ContentArea do? (Restricts which block types can be dropped in)
  6. What is the difference between Edit mode and Preview mode? (Edit shows overlays and allows changes; Preview is read-only)