MVC and the PageEditor

Developers seem to have had a bit of a love/hate relationship with Sitecore's PageEditor over the years but editors are becoming more and more reliant on the PageEditor. The increased reliance on Sitecore's PageÉditor means developers need to ensure the components they are building are PageEditor friendly to allow editors to take advantage of Sitecore's cool tools for creating great content and optimising their customers experience. The earlier developers start to consider PageEditor compatibility for components in a solution the cheaper it will be for all concerned and the greater the chance for the editors get a great set of tools to work with. There are some simple steps that can be taken to get started.

Views

When we present content on a view we have to ensure the output has been processed through the FieldRenderer pipeline in order to support page editor features. This is done in a view rendering using:

@Html.Sitecore().Field([field name])

If content generated in a components is retrieved directly from an item which results in the output only being read-only in page edit mode - an editor does get the option to open the standard content editor for the relevant item but this is not really what we are looking for. There is not a great deal of documentation regarding MVC and the Sitecore Page Editor but Sitecore has released a document to help developers (see reference below).

There are likely some issues which need to be addressed when working with Glass Mapper which probably require some changes to our model classes. I have not worked with Glass Mapper together with MVC before but there is a tutorial on the Glass website regarding MVC Page Editor Support (see references below) and everything seems do-able.

We also have to make sure editors have access to fields which are not visible on the front-end but which still relevant for editors, for example meta tag fields, otherwise there is a chance that they will be overseen by the editors. These should probably be identified as tasks but just wanted to give a heads up.

When constructing layouts we also have to support the ability to assemble a page from a library of components using the Page Editor’s Design mode which is also detailed in Sitecore's document (a lot of this we all ready do but good to have a read through).

Glass Mapper

If you are using Glass Mapper there are a couple of things to remember when working with view renderings that use models loaded using Glass.

The model must have a property to represent a Sitecore item ID

 

Your view render must inherit from the Glass.Mapper.Sc.Web.Mvc.GlassView class using your model as a type parameter

Change rendering of fields to the Glass page editor friendly methods: e.g.

@Editable(o => o.[field name])
@RenderImage(o => o.[field name], isEditable: true)
@RenderLink(o => o.[field name], isEditable: true)

Model

As long as your model has a property to represent the item id everything you should be ok. On a side note, Glass has a number of attributes that can be added to a model class and its properties. For example, e.g. [SitecoreType] can be applied to a class, [SitecoreId] can be used to indicate which property is the Sitecore item id and [SitecoreField] to show which properties are fields. The SitecoreField attribute also allows you to map a property name to a field name so if I have a field “My_Text” but would prefer my property to be called MyText then I can do this:

[SitecoreField("My_Text")]
public virtual string MyText { get; set; }  

Glass has a method, GlassCast, which allows the conversion of a Sitecore item to a specific type loaded by the default Glass.Mapper context and the cool thing is the data is read directly from the item avoiding any unnecessary calls to the Sitecore data layer.

var model = myItem.GlassCast<MyModel>();

View

Instead of specifying the model that is to be used in your view render, you should make your view inherit from the Glass.Mapper.Sc.Web.Mvc.GlassView class using your model as a type parameter, for example:

@inherits Glass.Mapper.Sc.Web.Mvc.GlassView<ItZynergyApS.Models.MyModel>

The GlassView class exposes a number of methods to support editable fields and edit frames.  The view can then be modified to render field content using the following methods:

@Editable(o => o.[field name])
@RenderImage(o => o.[field name], isEditable: true)
@RenderLink(o => o.[field name], isEditable: true)

PageEditor Unfriendly field types

There are some field types which are not supported by the page editor this includes multilists, treelists and checkboxes. The standard Sitecore way is to use an EditFrame to access these field types - if you have not come across the EditFrame before it can be used (amongst other things) to open a window displaying the required field in a minimal content editor display so editors can maintain the field values. However, Sitecore as standard does not support the use of EditFrames in MVC views. Luckily for us, Glass does using the BeginEditFrame method.

For editors to be able to open a the window to edit the contents of a field, we need to create one or more buttons that will be displayed on the EditFrame and which will open the field for editing when the editor click on them. The EditFrame buttons are created in the core database in the following folder:

/sitecore/content/Applications/WebEdit/Edit Frame Buttons

Here we can create a suitable folder structure for our edit frame buttons using the /sitecore/templates/System/WebEdit/Edit Frame Button Folder template. In the folder one or more items can be created based on the /sitecore/templates/System/WebEdit/Field Editor Button template which should be configured to give access to the specific PageEditor unfriendly field types.

For example, if I have an item with a multilist field called BackgroundImages, I can create a folder structure /sitecore/content/Applications/WebEdit/Edit Frame Buttons/Refresh/BackgroundImages and in the BackgroundImages folder and I create an item based on the /sitecore/templates/System/WebEdit/Field Editor Button template called “SelectableMedia”. On the “SelectableMedia” item, I specify one or more fields which should be displayed in the edit frame - here I enter BackgroundImages in the Fields field.

In the view rendering I then use the Glass method BeginEditFrame and send the path to my edit button folder along with the path of the datasource item, as our model inherits from the ItemBase we can use the Model.Path property:

@using (BeginEditFrame("/sitecore/content/Applications/WebEdit/Edit Frame Buttons/Refresh/BackgroundImages", Model.Path))
{
    // Some code to display images from the backgroundimages field
}
 

Then when we run in PageEdit mode and click in the area wrapped by the BeginEditFame, we are shown the available buttons which then can be clicked by an editor to open the PageEditor unfriendly field in a window for editing its content. 

RenderImage

Please note I have not been able find a way to use the RenderImage method on a collection of images for example when one has a collection of images selected using a multilist field.

IsInEditingMode

Glass has a handy method to determine if we are in PageEdit mode

@if (IsInEditingMode)
{
  // Do something
}

References:

Sitecore

Sitecore Page Editor Recommended Practices for Developers

Glass Mapper

There is a couple of tutorials regarding the Glass Mapper and the Page Editor here: http://glass.lu/Mapper/Sc/Tutorials/Tutorial14.aspx  http://glass.lu/Mapper/Sc/Tutorials/Tutorial22.aspx 

 

Latest articles