LibrarySites.Banner

Improving the Page Editor Experience Part 3: Detecting Page Mode

In the previous post, we looked at ways of ensuring authors are prompted to specify a data source for the components that require it by using datasource template and location restrictions. We also looked at ways of falling back to sample content, preventing components without content from being shown to a visitor.

 

This might make sense in the case of a gallery or banner - sample images could be provided and a visitor would be none the wiser. They are less likely, however, to be fooled by [YOUR HEADING HERE] in place of a missing component title.

The solution is to utilize Sitecore.Context.PageMode - if the site is being viewed in Page Editor mode and a component does not have a data source set, set it to a sample and disable web editing - otherwise, hide the component. Visitors will not see a work in progress:

if (source == null)
{
    if (Sitecore.Context.PageMode.IsPageEditor)
    {
        source = ItemReferences.SampleWidget;
 
        WidgetHeading.DisableWebEditing = true;
        WidgetText.DisableWebEditing = true;
        WidgetLink.DisableWebEditing = true;
        WidgetImage.DisableWebEditing = true;
    }
    else
    {
        this.Visible = false;
    }
}
else
{
    WidgetHeading.Item = source;
    WidgetText.Item = source;
    WidgetLink.Item = source;
    WidgetImage.Item = source;
}


Presentation, unlike content, is not versioned (by default, the Renderings field is shared - identical across numbered and language versions both) - by hiding empty components from visitors, you reduce the chance of a scheduled publishing job pushing incomplete or erroneous presentation changes into the production environment.

Detecting Page Mode using Javascript

You can also detect page mode using the Sitecore.PageModes object in Javascript - there is a Sitecore.PageModes.PageEditor object with more options, but detecting Sitecore.PageModes is enough for this example.

Consider the following example - you want to display a number of Twitter feeds on a page, but authors do need various feeds cluttering up the Page Editor interface. In this case, it is easier to move Page Editor detection from server side to client side.

Below is a modified version of the standard Twitter widget, modified to accept Sitecore.PageModes. If it exists, we are in Page Editor and the widget is not displayed; as authors, we do not need to see external feeds when modifying content:

<script>
    var mode = Sitecore.PageModes;
    ! function (d, s, id, pagemode) {
        var js, fjs = d.getElementsByTagName(s)[0],
            p = /^http:/.test(d.location) ? 'http' : 'https';
        if (pagemode == null) {
            if (!d.getElementById(id)) {
                js = d.createElement(s);
                js.id = id;
                js.src = p + "://platform.twitter.com/widgets.js";
                fjs.parentNode.insertBefore(js, fjs);
            }
        }
    }(document, "script", "twitter-wjs", mode);
</script>


In Preview (or live) mode, the feed appears:

Twitter feed

In Page Editor mode, it doesn't:

Twitter feed replaced by text in Page Editor mode

We now have various methods of hiding, showing, and replacing content depending on whether or not the site is being viewed in Page Editor. In part 4, we will look at at how you can support the Page Editor as a front-end developer by writing CMS-friendly HTML and CSS.

  • In Razor views, I commonly use blocks like this:  @if (@Sitecore.Context.PageMode.IsPageEditorEditing)     {  }  or also  @if (@Sitecore.Context.PageMode.IsPageEditor || @Sitecore.Context.PageMode.IsPreview)    {  }  when the page design fights with the page editor, I insert CSS to fix the page to allow it to display correctly when it's being edited.

  • Thank you, really helpful. One suggestion though. `null` and `undefined` are not the same in javascript. In preview and live mode in Sitecore 7.5, the `Sitecore.PageModes` returns `undefined`.  if  (typeof pagemode === 'undefined') {     ... };