Table of Contents
Introduction
This document describes editing
of content such as pages and blocks in the EPiServer CMS user interface.
EPiServer
CMS has a plugable user interface where you can plug-in your own gadgets to the
panes in the user interface. The UI framework has a server-side part based on
ASP.NET MVC and a client side part using the JavaScript library Dojo. The UI
also has context awareness where it is possible to have a
component to automatically reload when the context is
changed, to display customized content for that item. There is also support for loading Web
Form pages and user controls into components of the user interface, making
it possible to port existing plug-ins built with ASP.NET user interface.
Editing Your Content in Different Ways
The editing concept includes different possibilities for editing content in the user interface:
- Side-by-side Editing opens up a light weight pane next to the content
where the user can edit the content. As the user changes the settings in the pane
the display is updated directly so that the editor instantly can see the results on the page.
- Inline Editing creates an editor directly on the page. This is currently used
for simple property types like short strings, integers and decimal numbers.
- Forms editing is where you can edit all properties in a form based editing view.
Here you are able to edit properties that are not visible on the page.
This means that the editor can
do changes using different modes without loosing context or having to save.
Autosave and Undo/Redo
When an editor does a change to the content this is automatically saved to the client
state. These changes are then sent to the server to be persisted. To reduce the
burden on the server there will be a slight delay of a few seconds before synchronizing
the client state with the server. When a user is done editing a property or content
block an undo step will be created. This undo history is kept on the client and
enables the user to undo and redo changes. The undo-redo steps are available until
the user leaves the page while the latest changes are always sent to the server
and will be available even if the user leaves the page or closes the browser.
Architecture
The page editor is composed of two “layers”. The first is the UI layer, where most
of the EPiServer scripts and css files are loaded and where most of the user interface
and interaction take place. The second layer is the actual content page being edited.
This layer is placed inside an iframe and should have very few differences compared
to the page that is shown to visitors of the site. The only difference are HTML5
data-attributes injected in edit mode to make it possible for the content close
editing to identify editable blocks. A custom stylesheet is injected into the content
pages when editing is enabled, but there are however no other scripts or markup
injected. When the second layer is loaded the UI layer will scan
the content of the page to find nodes that should be editable and add event handlers
to them that will trigger loading of the correct editor.
The simplest way of enabling editing for a specific area is to add the following
attribute to the HTML tag: data-epi-property-name="PageName":
XML
<h1 data-epi-property-name="PageName"><%= CurrentPage.PageName %></h1>
When using EPiServer property web control will automatically output data attributes when the
page is displayed in page editing mode.
As a property can be displayed several times on a page, it can also be edited in multiple places.
By editing one of them, all the other will be updated as well. A property can be disabled, in which cannot be
edited, but it will update its content if the property is edited elsewhere.
In this case we tell the editor that clicking on the following node should load
whatever editor is configured for the “Pagename” property. Configuration of editors
is done separately and does not have to be added to the HTML even if there are a
few other data-attributes that you can use to override default behaviour.
When an editor is triggered for a property we need to figure out which editor should
be used for that property. An editor factory class creates the editor based on the data attributes
and metadata for the property. EPiServer Framework has a system for extracting metadata
that can be used to create an editor. The metadata is created from several sources.
- Extracting metadata attributes from the model class
- Global “editor descriptors” that can set up rules for a common language runtime
type.
- Custom metadata providers that supplies the metadata.
A more detailed description of the EPiServer object editing system is available in
the EPiServer Framework SDK.
Since EPiServer has support for creating page properties both from typed model classes
and manually in the administrative user interface, the PageData class has a custom
metadata provider assembling metadata depending on settings in the database.
The metadata is sent to the client using a RESTful service and is a hierarchical
representation of the page and its properties. Below is an example of how a property
might be described:
{
"name":"PageName",
"modelType":"EPiServer.Core.PropertyString",
"uiType":"dijit.form.ValidationTextBox",
"uiPackage":null,
"customEditorSettings":{"uiWrapperType":"inline","uiType":"epi.cms.widget.ValidationTextBox"},
"layoutType":null,
"defaultValue":null,
"displayName":"Name",
"groupName":null,
"displayOrder":-81,
"settings":{"label":"Name","required":true,"missingMessage":"The Name field is required.","invalidMessage":"The
field Name must be a string with a maximum length of 255.","regEx":"^.{0,255}$","maxLength":255},
"additionalValues":{},
"properties":[],
"groups":null,'
"selections":null
}
Some of the parts to highlight are:
- modelType is the name of the CLR type including its namespace.
- uiType is the default client side editor widget.
- customEditorSettings might have information about a non-standard editor type like
an inline editor.
- settings is a settings object that will be passed to the constructor of the editor
widget.
Server Communication
Page editing component creates editable blocks for each node in the page with data attributes.
Page data is stored in the page model and page editing syncs changes using the page model server sync class.
The editable blocks are responsible for editing property data. The page model is updated
during editing. The editable blocks uses a render manager to render property on the page. This
can be client side rendering or server side. Server side rendering is throttled with a queue to
make sure we do not try to render too many properties at the same time. Changing one property
could cause several properties on the page to need to be rerendered with different settings.
Editable Block
Clicking on an editable block opens up the editor for the block. The editor and an editor wrapper is created the on the first click.
The wrappers purpose is to display the editor. An inline editor wrapper is used
for inline editor and a dialog editor is for displaying the editor in a dialog. The editor factory decides
which wrapper and editor to use depending on the data attributes for editing and metadata for the
property. It is possible to connect to an event in editor factory to be able to change the values at runtime.
The data attributes has higher precedence than the metadata. A developer can choose to use an
editor for a property on a page which is not the standard editor for that property. For inline
editing we must use an editor designed for it. In all other cases the editor is a widget.
Editing Data Attributes
Attribute |
Required |
Type |
Description |
data-epi-property-name |
Yes |
String |
Name of the property. |
data-epi-disabled |
No |
Boolean |
It is not possible to edit this node but we want the node to be updated if the property value changes. |
data-epi-useoverlay |
No |
Boolean |
Use overlay when mouse hovers above node to edit. |
data-epi-property-render |
No |
String |
|
data-epi-property-edittype |
No |
String |
Type of wrapper to display editor in. Possible values are: flyout (default),
inline, webcontrol. Inline editing is only possible with custom inline editing widgets. Dijit widgets cannot be used inline. |
data-epi-property-editorsettings |
No |
JSON |
Any settings for editor. |
data-epi-property-rendersettings |
No |
JSON |
Settings used to specify rendering, for example custom tag. |
data-epi-property-editor |
Optional |
String |
Type name of property editor widget |
The values for data-epi-property-editorsettings and data-epi-property-rendersettings can be set through properties
EditorSettings or RenderSettings on either Property web control
or on Property data control when using web forms. In MVC the
values can be passed in as anonymous object to PropertyFor helper method. The render settings should be passed in using parameter 'additionalViewData' while
the editor settings can be passed in using parameter 'editorSettings'.
Overall Architecture
Do you find this information helpful? Please log in to provide feedback.