November Happy Hour will be moved to Thursday December 5th.

Linus Ekström
Oct 18, 2012
  17849
(2 votes)

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

Oct 18, 2012

Comments

Oct 18, 2012 12:24 PM

Great. Looking forward reading more in this series.

Rene Sprietsma
Rene Sprietsma Jan 16, 2013 06:00 PM

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' ?





Jan 17, 2013 03:15 PM

@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.

Feb 25, 2013 04:24 PM

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:



I done something wrong?

Feb 26, 2013 01:07 PM

@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?

Mar 4, 2013 02:18 PM

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

I have a button in the aspx file:


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...

Mar 12, 2013 04:05 PM

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

Mar 15, 2013 03:50 PM

Cool, it's working now. Thanks!

dannymurphy
dannymurphy Jun 19, 2013 11:15 AM

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
{
// PartialContentController override
//public override ActionResult Index(IContentData currentContent)
//{
// return View();
//}

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

tried both derriving from ActionControllerBase and PartialContentControler 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

Jun 24, 2013 04:09 PM

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).

smithsson68@gmail.com
smithsson68@gmail.com Aug 21, 2013 01:04 PM

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.

Aug 21, 2013 01:09 PM

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.

Dec 11, 2013 03:11 PM

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

Dec 11, 2013 04:04 PM

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.

Fredrik von Werder
Fredrik von Werder Apr 16, 2014 03:00 PM

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?

Apr 18, 2014 08:16 AM

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

Ted
Ted Jun 24, 2014 05:51 PM

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 comment.
Latest blogs
AsyncHelper can be considered harmful

.NET developers have been in the transition to move from synchronous APIs to asynchronous API. That was boosted a lot by await/async keyword of C#...

Quan Mai | Dec 4, 2024 | Syndicated blog

The search for dictionary key

Recently I helped to chase down a ghost (and you might be surprised to know that I, for most part, spend hours to be a ghostbuster, it could be fun...

Quan Mai | Dec 4, 2024 | Syndicated blog

Shared optimizely cart between non-optimizley front end site

E-commerce ecosystems often demand a seamless shopping experience where users can shop across multiple sites using a single cart. Sharing a cart...

PuneetGarg | Dec 3, 2024

CMS Core 12.22.0 delisted from Nuget feed

We have decided to delist version 12.22.0 of the CMS Core packages from our Nuget feed, following the discovery of a bug that affects rendering of...

Magnus Rahl | Dec 3, 2024