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

Gadgets - Developers Tutorial

Product version:

EPiServer CMS 6 / 6 R2

Document last saved:

The dashboard is one of the new features of EPiServer 6 which is also a plug-in area open to partners. Usages include presenting high-level information or provide quick access to common tasks. This document is a tutorial to creating gadgets on the dashboard.

While this document highlights aspects related to gadget development with code examples keep these external resources handy for in depth information:

  • The OnlineCenter Developer documentation.
  • QuickChat project, Zipped C# project: Quick and dirty output from this tutorial
  • Dynamic DataStore SDK: Documentation and examples on the data store
  • Up-to-date info on ASP.NET MVC

 

Important Note Regarding MVC Version

The information in this technote applies to both EPiServer CMS 6.0 and EPiServer CMS 6 R2 but with one important difference:

  • EPiServer CMS 6.0 requires MVC 1.0
  • EPiServer CMS 6 R2 requires MVC 2.0

 

Contents

OnlineCenter overview

Setup

Starting out with gadgets

Gadget Development, step 1: Showing Information

Gadget Development, step 2: Server Interaction

Gadget Development, step 3: Client side development

Gadget development, step 4: Styles and CSS

Tutorial Download 

Further Information

Checklist: Playing nice on the dashboard

OnlineCenter Overview

EPiServer OnlineCenter, which is a new UI framework for EPiServer products, is introduced in EPiServer CMS 6. The main purpose of EPiServer OnlineCenter is to allow easier navigation and integration of different products – EPiServer products or 3rd party products. EPiServer OnlineCenter is made up of two main components:

Global Navigation

The global navigation helps users navigate different integrated products such as EPiServer CMS, EPiServer Community, and EPiServer Mail but also third party products as ImageVault or similar integrated modules which would like to expose their interfaces to the logged on user.

The global navigation can be customized (it’s a new plugin-area) and it’s possible to insert the menu into both (custom) web forms and MVC views.

The menu is designed to be oriented on products and modules, so that each top menu item represents a product while the sub level menu contains the actual views/functions/parts of the product.

 

Dashboard

The main purposes of the dashboard are to aggregate site information and expose important functions to the user. For example showing a list of recently changed pages so that the editor quickly can get back to work where they left off.

The dashboard is made up of tabs, zones and gadgets. Gadgets can easily be created (ASP.NET MVC) and plugged into the dashboard so that the user can use them (add to dashboard). A gadget is a self contained item and is responsible for its own rendering and behavior. A gadget can either contain functionality that can be used within the gadget interface or simple link away to other products integrated in the framework (for example; a direct link to CMS  / Pages where you can use the classic editing mode features).

Setup

Start by installing an EPiServer CMS 6 web site using the standard installer. Using the default options you will end up with a web site in c:\EPiServer\Sites\[MySiteName]. In the example below this site was installed in c:\EPiServer\Sites\ExampleEPiServerSite4. While it’s not required for normal operation this tutorial assumes you have installed ASP.NET MVC.

Develop gadgets in separate project

The module is created as a separate project below the “public” folder of the EPiServer site. As an alternative to creating a separate project you can add you gadget to the existing PublicTemplatest project, please see the Develop gadgets in public templates project section for more information.

Add a unit test project if you like. This tutorial will not cover unit testing.

As you can see in the screen shot when enabling “Show all files” the quick chat module is placed below the development site.

 

Modifications to default

Some modifications are recommended to the default MVC application.

1.      Remove default controllers and views

Remove the default controllers, views and scripts (HomeController.cs, /Views/Home, etc.) according to the image below. You can always use another project to play with ASP.NET MVC. Please note that if you have added a unit test project you also have to remove all the related test functions from the QuickChat.Test project.

2.      Clean up web.config

The web configuration is inherited from the public templates site but if you leave some settings in the module’s web.config you won’t kill intellisense. Copy the root web.config file (not the one in the Views folder) from the QuickChat example zip to your project.

3.      Change output path

Open the QuickChat project's properties and change the default build output path of the quick chat project to “..\..\bin\”

4.      Add references

Add references to EPiServer.Shell and EPiServer.Data. You will need these later on. You can find a copy of these in the public template’s bin folder.

5.      Register module in web.config

Open the public templates’ web.config file and find the episerver.shell configuration section. Add the quick chat module to the /configuration/episerver.shell/modules/ path. This is an excerpt of the added configuration:

<episerver.shell>
    <publicModules rootPath="~/modules/" autoDiscovery="Minimal">
        <!-- QuickChat is assumed to be located in ~/modules/QuickChat -->
        <add name="QuickChat">
            <assemblies>
                <add assembly="QuickChat"/>
            </assemblies>
        </add>
    </publicModules>

 

Develop gadgets in public templates project

While creating gadgets in a separate project as described in the Create gadgets in separate project section often is a good approach it’s also possible create gadgets in the PublicTemplates.csproj project by doing some modifications to configuration and the csproj file.

1.      Configuration

The Public Templates needs to be registered in the configuration/episerver.shell/publicModules configuration section. The resourcePath attribute tells the system to look for views (which are described later in this document) in the folder /Views/[ControllerName]/[ActionName].ascx instead of the default location below the modules folder. Also update the add assembly section to any new name chosen for the public templates application.

<episerver.shell>
     <publicModules rootPath="~/modules/" autoDiscovery="Minimal">
          <add name="Public" resourcePath="~/">
               <assemblies>
                    <add assembly="EPiServer.Templates.Public" />
               </assemblies>
          </add>

 

2.      References

Add references to “System.Web.Mvc”, “EPiServer.Shell” and “EPiServer.Data”.

3.      Create Folders

The ASP.NET MVC framework suggests you organize the code in below three folders: “Controllers”, “Models” and “Views”. Add these folders to your project.

4.      Visual Studio Integration

ASP.NET MVC includes some wizards to help out in the task of creating controllers and views. These are not enabled in the PublicTemplates.csproj installed with EPiServer CMS but they can be with some manual tweaking of the file. Right-click on the project and “Unload”, then “Edit …” it. Add {603c0e0b-db56-11dc-be95-000d561079b0}; to the list of existing project type guids. Now save, right click “Reload Project”.

<Project>
     <PropertyGroup>
          <ProjectTypeGuids>{603c0e0b-db56-11dc-be95-000d561079b0};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

 

Starting out with gadgets

It’s time to create a gadget. Head to the QuickChat project, right click on the “Controllers” directory and “Add Controller”.

Add the gadget attribute to the controller template created for you. To reduce Time-to-dashboard we change the return statement to return html content directly (we’ll change this soon).

using System.Web.Mvc;
using EPiServer.Shell.Gadgets;

namespace QuickChat.Controllers
{
     [Gadget]
     public class QuickChatController : Controller
     {
          public ActionResult Index()
          {
               return Content("<strong>Some</strong>thing!");
          }
     }
}

Now compile and switch over to the dashboard. Click on the (+) symbol of QuickChat in “Add Gadgets…” to add this new gadget. Now that we’ve got “Something” out on the dashboard we can move on to more serious business.

A tiny bit of background

Dashboard gadgets are developed using the MVC model. From the point of view of processing a server request this model can be described like this:

Incoming Request » Controller Action » View » Outgoing Response

The “Controller Action” and “View” represents code that is developed to provide functionality. The arrows (») represent pluggable points provided by the ASP.NET MVC framework.

In a typical ASP.NET MVC application the flow spans over a complete page request. However, in the case of our dashboard gadgets this is slightly different:

Incoming Request » Dashboard Controller Action » Dashboard View
     foreach (gadget on userDashboard)
     { 
          Partial Request » Controller Action » View 
     } » Outgoing Response

Dashboard gadgets uses the same principles as a typical MVC application but only renders a portion of the dashboard.

 

Gadget Development, step 1: Showing Information

With something now presented on the dashboard and a little background behind us we can let the coding begin.

Models

Add a class Message to the Models directory of the quick chat project.

using System;
namespace QuickChat.Models
{
     public class Message
     {
          public string Text { get; set; }
          public string From { get; set; }
          public DateTime Sent { get; set; }
     }
}

The model represents another pillar of the MVC architecture. This describes the data we interact with using the controller and show in our views.

Controller

Going back to the QuickChatController and use EPiServer.Data to retrieve messages from the database (take a look at the EPiServer Framework Reference SDK for in-depth information about the Dynamic Data Store):

[Gadget]
public class QuickChatController : Controller
{
     // since the controller is created for each request
     // we can assign a store as a variable
     static QuickChatController()
     {
          DynamicDataStoreFactory.Instance.CreateStore(typeof(Message));
     }

     DynamicDataStore store = DynamicDataStoreFactory.Instance.GetStore(typeof(Message));

     public ActionResult Index()
     {
          // select all messages for the last 5 minutes
          var fiveMinutesAgo = DateTime.Now.AddMinutes(-5);
          var messages = from m in store.Items<Message>()
               where m.Sent > fiveMinutesAgo
               select m;

     // pass the messages to the view
     return View(messages.ToList());
}}

The code will select all recent messages and pass them to the “Index” view for display.

Views

Create an MVC partial view in the quick chat project.

The wizard can be conjured by right-clicking in the controller action and choosing “Add view…” (requires ASP.NET MVC to be installed).

When the view is located in Views/QuickChat/Index.ascx in the quick chat project it will be automatically selected to show the messages.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IList<QuickChat.Models.Message>>" %>
<%@ Import Namespace="QuickChat.Models" %>
<div class="epi-defaultPadding">
     <ul>
     <% foreach (Message m in Model) { %>
          <li><%= m.From %>: <%= m.Text %></li>
     <% } %>
     </ul>
     Number of messages: <%= Model.Count %>
</div>

The view shows messages passed to it by the controller which is just about enough when adhering to the MVC pattern. 

Gadget Development, step 2: Server Interaction

So far we have created a gadget that shows messages in the database but there is no way to put the messages in. That is precisely what is going to be fixed.

Posting messages to the controller

The most convenient option for posting information from the dashboard is using AJAX. This release includes an extension method that helps out doing this:

<%@ Import Namespace="EPiServer.Shell.Web.Mvc.Html" %>
<div class="epi-defaultPadding">...</div>
<hr />
<% Html.BeginGadgetForm("Save"); %>
     <input name="text" />
     <%= Html.AcceptButton() %>
<% Html.EndForm(); %>

The new improvement of the view renders a form with a text input field and a submit button. Since we used a “gadget form” the form will be serialized and posted using jQuery.ajax. The results of the “Save” action will replace any existing content in the gadget.

Taking care of posted messages in the controller

The controller accepts the posted message and stores it in the store. The view that is returned will take the place of the existing view in the gadget area. The mapping of the posted message string to input parameters is a feature of ASP.NET MVC. Refer to the blogosphere for documentation on form posting scenarios.

public ActionResult Save(string text)
{
         // store the posted message
         Message message = new Message();
         message.Text = text;
         message.From = User.Identity.Name;
         message.Sent = DateTime.Now;
         store.Save(message);
         var messages = GetRecentMessages();

         return View("Index", messages);
}

     IList<Message> GetRecentMessages()
     {
         return (from m in store.Items<Message>()
                 where m.Sent > DateTime.Now.AddMinutes(-1)
                 orderby m.Sent
                 select m).ToList();
     }

 

Gadget Development, step 3: Client side development

While server development is great it’s what you do on the client that makes your projects shine.

You may have noticed that the chat gadget at this point still isn’t very interactive. While you get updates when refreshing the page, or posting messages it’s just sits there in between.

Defining resources

First of all is getting out on the dashboard with all the other gadgets. The recommended way of doing this is using an attribute on the controller, as below:

[Gadget]
[EPiServer.Shell.Web.ScriptResource("Content/QuickChat.js")]
public class QuickChatController : Controller
{
}

This will declare a java script file located in the Content directory of the quick chat module which will be loaded with the dashboard. The script is loaded every time the dashboard is displayed, regardless if there are any quick chat gadgets or not, so takes care to put stable code in the javascript file.

While the script is executed each time the dashboard loads the way to associate with a gadget instance are client script init methods:

[Gadget(ClientScriptInitMethod = "quickchat.init")]
[EPiServer.Shell.Web.ScriptResource("Scripts/QuickChat.js")]
public class QuickChatController : Controller

 

Client scripts

The script resource attribute assumes a JavaScript method “quickchat.init” is present on the client. Let’s take a look on this method in the quickchat.js file:

(function($) {
    // using this pattern helps keeping your privates private
    quickchat = {};
    quickchat.init = function(e, gadget) {
        setInterval(function() {
            // reload on an interval unless typing
            var typedText = $("input[type='text']", gadget.element).attr("value");
            if (!typedText) {
                gadget.loadView("Index");
            }
        }, 5000);
    };
})(epiJQuery);

The init method is invoked by the dashboard and starts updating the gadget every five seconds. While this represents an easy way to update the gadget regularly it’s not particularly suited for a chat since it will steal focus from the text box.

Gadget development, step 4 - Styles and CSS

The best way to get your own style sheets out on the dashboard is defining them for your gadget as in this snippet:

[Gadget(ClientScriptInitMethod = "quickchat.init")]
[EPiServer.Shell.Web.CssResource("Content/QuickChat.css")]
public class QuickChatController : Controller

By using the attribute on the gadget controller and creating a css file in the Styles folder of your gadget proejct you can define styles specific to your gadget. There are also shared styles you can use to get a consistent look and feel. This is described in a later section of this document. 

Tutorial Download

Download the Quick Chat Gadget code sample in zip format.

Further Information

Styling

The CSS styles used on the Dashboard resets many of the default styling of elements added by the browser and in some cases adds an own default style. This styling may however not be enough (it’s rather none styled) so to the rescue comes some additional convenient classes. Documentation about styling and the can be found in the OnlineCenter Developer document

Checklist: Playing nice on the dashboard

Making a gadget means sharing a common workspace with others. Take a moment to review this list before publishing your gadget to a wider audience:

  • “Namespace” your CSS classes
  • Namespace and encapsulate your JavaScript methods to avoid polluting global namespace
  • Don’t override other gadget’s styles
  • Don’t assume other gadgets will stay the same
  • Never assume there is only one gadget of your kind (affects element id:s)
  • Prefer documented CSS classes for a consistent look and feel over time
  • Avoid long-running operation (such as reports or RSS operations) from your default action