Views: 13510
Number of votes: 2
Average rating:

Extending the User Interface of EPiServer 7

You have probably not missed that EPiServer 7 comes with a brand new user interface for content editing. This is built on top of a new UI-framework that is also used on the new dashboard. In this blog series I’ll explain how to implement some of the most common extension scenarios.

Note: The code in this blog series is based on the latest build and might not work in EPiServer 7 preview or other later builds.

How the UI is built up

In previous versions of EPiServer CMS the user interface consisted of a simple page containing a table structure with a bunch of iframes where each function was plugged in or in some cases hard coded. The page was running in quirks document mode to enable resizing of the each iframe.

In EPiServer 7, the UI-framework that is used to build the dashboard and CMS edit view works quite different:

  1. A simple page is loaded. It contains some script and styling references and a JavaScript bootstrapper that is responsible for setting up the UI.
  2. The bootstrapper fetches the components for the specific view using a REST-based store, start them up and adds them to their correct hierarchical placement.

All this is done on the client using the JavaScript framework Dojo. It’s still possible to use your jQuery-style gadgets to plug in to the new UI-framework but writing components in Dojo will give you more built in functions and styling for free. It’s up to you to decide what suits your needs and skills best.

If you are new to Dojo (which I guess most of you are) there is an introduction section in the framework SDK that points to some good resources to get started. For instance, there are some good tutorials here:

Setting up a module

If you don’t already have a shell module set up we need to add this to be able to add plug-ins to the user interface. The simplest way to get started is to add the following configuration into a file named module.config to the root folder of your site:

<?xml version="1.0" encoding="utf-8"?>
<module>
    <assemblies>
        <!-- This adds the Alloy template assembly to the "default module" -->
        <add assembly="EPiServer.Templates.Alloy" />
    </assemblies>
 
    <dojoModules>
        <!-- Add a mapping from alloy to ~/ClientResources/Scripts to the dojo loader configuration -->
        <add name="alloy" path="Scripts" />
    </dojoModules>
</module>

Note: The assembly should match the name of your template assembly in this case.

Using web forms

We recommend writing your plug-ins using Dojo or potentially jQuery to get a nice integrated look and feel. Sometimes you just want to add something simple or quickly convert a plug-in for CMS 6 –> 7. To enable this we have added an attribute to be able to load a web forms page or user control inside an iframe. A simple example of this could look like this:

using EPiServer.Shell.ViewComposition;
using EPiServer.UI;
using EPiServer.Web;
 
namespace EPiServer.Templates.Alloy
{
    [IFrameComponent(Url = "~/IFramePageExample.aspx",
        ReloadOnContextChange = true,
        PlugInAreas = "/episerver/cms/assets",
        Title = "Iframe test",
        Categories="cms",
        MinHeight = 100,
        MaxHeight = 500)]
    public partial class IframePageExample : ContentBaseWebForm
    {}
}

 

Note: We are inheriting from the class ContentBaseWebForm that is located in the EPiServer.UI assembly since we want to be able to handle all content types and not just pages. The attribute itself is defined in the EPiServer.Shell assembly.

Update: In EPiServer 7.5, the base class to use is: EPiServer.Shell.WebForms.ContentWebFormsBase

ReloadOnContextChange: Can be defined to reload the iframe content with a new content id each time the user changes context.

PlugInPaths: Can be used to auto-plug in a component into a given location in the user interface.

Categories: Defines where this components can/should be added. The current implementation is to only show components to the user that matches the category of the view. Currently used categories are “cms” and “dashboard” but we will probably add more categories as we convert more views to the new framework.

To see that we are loading the current item we add a simple output of the name in the code-front file:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="IframePageExample.aspx.cs" Inherits="EPiServer.Templates.Alloy.IframePageExample" %>
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
</head>
<body>
    <form id="form1" runat="server">
    <div>
<%
   1: =CurrentContent.Name 
%>
    </div>
    </form>
</body>
</html>

Which will result in the following in the UI:

IFrameTestComponent

 

We will continue writing more samples and update the links below:

Extending the User Interface of EPiServer 7

Creating a Dojo based component

Creating a content search component

Adding a more advanced property editor

    (By Per Nergård , 18 October 2012 12:24, Permanent link)

    Great. Looking forward reading more in this series.

    (By Rene Sprietsma , 16 January 2013 18:00, Permanent link)

    The example does not compile with version EPiServerCMS7.0.586.1.

    ComponentAttribute.PlugInAreas Property is a string value.

    Can you explain a bit more about the 'PlugInPaths = PlugInAreas.AssetsPanel' ?





    (By Linus Ekström , 17 January 2013 15:15, Permanent link)

    @Rene: I have updated the sample code to work with the EPiServer 7 release. Regarding PlugInAreas as a string, for the new user interface we use strings as identifiers in many cases where we might have used enums before. The reason for this is simply to be more extendable. For instance, the attributes defined on the Framework level should have no knowledge of our products of potential third party code that want's to create plug in areas.

    Since we are using strings as identifiers, we have added classes with constant strings to help you developers. In this case, the plug-in-area is currently defined in the EPiServer.CMS.Shell.UI-assembly. Since this is located in an add-on you have the option to take a dependency to this or just to use a hard coded string as in the changed example above. I will write a separate blog posts about the pros and cons about taking a dependency to an add-on.

    (By Botond Kupan , 25 February 2013 16:24, Permanent link)

    I added a button the the Html and an eventhandler in codebehind, but by pressing the button, after postback the current page is reloaded in the window:

    <asp:Button ID="ReindexButton" runat="server" OnClick="ReindexButton_Click" Text="Reindex page in Siteseeker"/>

    I done something wrong?

    (By Linus Ekström , 26 February 2013 13:07, Permanent link)

    @Botond: Clicking on a button in web forms WILL do a post back since that's how web forms work. Or are you meaning something else?

    (By Botond Kupan , 04 March 2013 14:18, Permanent link)

    No, I mean, I implemented everything that you describe in the top.

    I have a button in the aspx file:
    <asp:Button ID="ReindexButton" runat="server" OnClick="ReindexButton_Click" Text="Reindex"/>

    I have the event in the codebehind:
    public void ReindexButton_Click(object sender, EventArgs e)
    {...}
    When I click on the button, the event is not fired, and instead of the page where the button was clicked, is loading the page that is opened in the Episerver editor.

    Very strange...

    (By Linus Ekström , 12 March 2013 16:05, Permanent link)

    @Botond: I have reported a bug for the issue. The work around is to turn of the FURL handling for the current request. Here's a code sample on how to do it:

    protected override void OnLoad(EventArgs e)
    {
    base.OnLoad(e);

    if (UrlRewriteProvider.Module != null)
    {
    UrlRewriteProvider.Module.FURLRewriteResponse = false;
    }
    }

    (By Botond Kupan , 15 March 2013 15:50, Permanent link)

    Cool, it's working now. Thanks!

    (By dannymurphy , 19 June 2013 11:15, Permanent link)

    Hi,

    Can you use the IFrameComponent with MVC ?

    I have been trying the following :
    [EPiServer.Cms.Shell.ViewComposition.IFrameComponent( Url="~/MyPlugin", ReloadOnContextChange=true, PlugInAreas=EPiServer.Cms.Shell.PlugInArea.AssetsPanel, IsAvailableForUserSelection=true )]
    public class MyPluginController : ActionControllerBase //PartialContentController<IContentData>
    {
    // PartialContentController override
    //public override ActionResult Index(IContentData currentContent)
    //{
    // return View();
    //}

    public ActionResult Index()
    {
    return View();
    }
    }

    tried both derriving from ActionControllerBase and PartialContentControler<IContentData> but still no joy.

    I have defined my assembly in the module.config file.

    I can see the request made for my controller from the browser.
    http://localhost:37002/MyPlugin/Index?uri=epi.cms.contentdata%3A%2F%2F%2F496267_497264&id=496267_497264

    But it never hits my controller action and returns a 404.

    I've tried adding the route in the EPiServer.Global.RegisterRoutes override but then the plugin just loads the main controller template for the Home Page?

    Is there any example of creating a simple IFrameComponent in MVC ? What I need to derrive from, any config needed ?

    regards,
    Danny

    (By Linus Ekström , 24 June 2013 16:09, Permanent link)

    Hi Danny!

    There is no built in support at the moment for this at the moment but you can add it yourself without to much hassle. First, you need to add the standard MVC controller route in an initialization module:

    RouteTable.Routes.MapRoute("StandardMvcRoute", "{controller}/{action}", new { action = "index"});

    Then you also need to add a model binder that resolves the URL part of the query string to a ContentData object (comes in the format uri=epi.cms.contentdata://8_176).

    (By smithsson68 , 21 August 2013 13:04, Permanent link)

    Hi,

    Is it possible to create an edit panel plug-in using this technique? If so what would the PlugInAreas string be. I have tried "episerver/cms/editpanel" but I can't see my plug-in.

    /Paul.

    (By Linus Ekström , 21 August 2013 13:09, Permanent link)

    It's currently not possible to add different views of a content the same way as you could in the edit panel of EPiServer 4-6. We are currently working on implementing support to configure different views for a content for the next release. This the goal is mainly to support internal needs this will probably simplify this. We're still early in the implementation process so I won't promise anything but we'll of course document this if we feel that it's in a state that's usable by partners.

    (By Henrik Ljungdahl , 11 December 2013 15:11, Permanent link)

    Is ContentBaseWebForm removed from EPi 7.5? It seems to be removed from the assembly.

    (By Linus Ekström , 11 December 2013 16:04, Permanent link)

    Try using EPiServer.Shell.WebForms.ContentWebFormsBase (still in the EPiServer.UI assembly). I'll have a blog post around this and some other changes soon.

    (By Fredrik von Werder , 16 April 2014 15:00, Permanent link)

    Can I use this Iframe method to list pages (links to epi pages) and make them draggable into a Content Area?

    I tried just with normal links but that didn't work.

    What is needed to make the links drag & dropable?

    (By Linus Ekström , 18 April 2014 08:16, Permanent link)

    @Freguz: Making drag and drop from another iframe is quite tricky. I would recommend this approach instead: http://world.episerver.com/Blogs/Linus-Ekstrom/Dates/2012/11/Creating-a-component-that-searches-for-content/

    (By Ted , 24 June 2014 17:51, Permanent link)

    Here's an example based on EPiServer 7.5 (or .6, rather) with MVC for an edit-mode widget: http://tedgustaf.com/blog/2014/6/create-an-episerver-widget-for-edit-mode/

  Please login to post a comment