Setting up a SDL Tridion 2011 GUI extension in 8 steps

This tutorial shows how to configure an extension for the SDL Tridion 2011 GUI from start to finish.

Introduction

The new 2011 SDL Tridion GUI framework is a major overhaul to the way extensions have been previously developed. The framework now is far more robust and well designed. Building new and exciting extensions has never been easier. However, configuring your extension may not be the easiest thing in the world to do...

The following tutorial steps show how to configure an extension for the SDL Tridion 2011 GUI from start to finish.

The example configuration and code is based on my extension: The Item XML Display.

The Steps

1. Decide on a disk location (typically on the CMS server) where you will create your extension in. Something like: ''C:\Extensions'' will do.

2. Create a ''config'' folder under your chosen location (c:\Extensions\config).

3. Create an ''extension.config'' file in your ''config'' folder.

4. Start with the following XML, simply copy it into the ''extension.config'' file:

<?xml version="1.0??>
< Configuration xmlns="http://www.sdltridion.com/2009/GUI/Configuration/Merge" xmlns:cfg="http://www.sdltridion.com/2009/GUI/Configuration" xmlns:ext="http://www.sdltridion.com/2009/GUI/extensions" xmlns:cmenu="http://www.sdltridion.com/2009/GUI/extensions/ContextMenu">
< resources cache="true">
< cfg:filters/>
< cfg:groups/>
< /resources>
< definitionfiles/>
< extensions>
< ext:editorextensions/>
< ext:dataextenders/>
< /extensions>
< commands/>
< contextmenus/>
< localization/>
< settings>
< defaultpage>/Views/Default.aspx</defaultpage>
< navigatorurl>/Views/Default.aspx</navigatorurl>
< editurls/>
< listdefinitions/>
< itemicons/>
< theme>
< path/>
< /theme>
< customconfiguration/>
< /settings>
< /Configuration>

I recommend editing configuration XML, or any XML for that matter in Visual Studio. Besides syntax coloring and validation, VS has a nice feature to make it easier for us to know which elements go where using Intellisense. To enable this, simply right-click anywhere in the white space of the XML document. Click on "Properties" in the menu. On the right-hand side of the screen you should see the properties pane,

Click on the button to the right of the "Schemas" field. A dialog will open. In the dialog click on the "Add" button and browse to: <Tridion_home>\web\WebUI\Core\Schemas. Select all XSD files and click open.

Make sure that the "Use" column is checked for these schemas you selected.

Once you've done this, Visual Studio will validate your configuration file against these schemas and will also show you which elements and attributes can be added:

5. Next step is to add the necessary elements to your extension's configuration file:

a)  Creating a command

A command is what we extend through our script. This is the piece of code that will be executed when an action is taken by the User in the interface.

Under the "commands" element create a new "commandset" that looks like this:

<cfg:commandset id="2011Extensions.Commands.ItemXmlDisplay">
< cfg:command name="ItemXmlDisplay" implementation="Extensions.ItemXmlDisplay"/>
< cfg:dependencies>
< cfg:dependency>Extensions.Resources.Base</cfg:dependency>
< /cfg:dependencies>
< /cfg:commandset>

Notice the "implementation" attribute, this one points to the javascript object defined in the script file which you already have or about to create.

Dependencies can also be specified for this command, in this example this is a resource group we get to configure in the next step.

Both the "commandset" and the "command" elements should have their "id" and "name" attributes respectively set to a unique and preferably clear names.

b)  Creating a resource group

Inside the "cfg:groups" element create a new resource group for your extension.

A group allows to manage several resources, such as script and CSS files as one unit. Your group should include all of the files needed by the Extension that the GUI will send to the browser:

<cfg:group name="Extensions.Resources.ItemXmlDisplay" merger="Tridion.Web.UI.Core.Configuration.Resources.CommandGroupProcessor" merge="always">
< cfg:fileset>
< cfg:file type="style">/client/commands/ItemXmlDisplay/Styles/ItemXmlDisplay.css</cfg:file>
< cfg:file type="script">/client/commands/ItemXmlDisplay/ItemXmlDisplay.js</cfg:file>
< cfg:file type="reference">2011Extensions.Commands.ItemXmlDisplay</cfg:file>
< /cfg:fileset>
< cfg:dependencies>
< cfg:dependency>Tridion.Web.UI.Editors.CME</cfg:dependency>
< cfg:dependency>Tridion.Web.UI.Editors.CME.commands</cfg:dependency>
< /cfg:dependencies>
< /cfg:group>

Notice that for each resource file you need specify the type. For CSS specify "style" while for javascript files specify "script". The last item is extremely important to remember to configure, without it, the extension will not function. The "reference" type must match the "id" attribute of the "commandset" configured in the previous step.

c)  Creating the extension configuration

Now that we have all the dependencies in place, we are ready to configure the actual extension, meaning, what we want to extend in the GUI.

First, add an element under the "ext:editorextensions" like so:

<extensions>
< ext:editorextensions>
< ext:editorextension target="CME">

It is very important that the "target" attribute is set to: "CME".

Under the "editorextension" node you can extend different interface elements such as the context menus or the ribbon toolbar, etc. (The  Intellisense will show you the other elements possible to extend).

For this example we will look at how to extend the GUI context menu as well as the ribbon toolbar.

Context Menu Extension

Add the following elements to the "editorextension" element: <ext:editurls/>

<ext:listdefinitions/>
< ext:taskbars/>
< ext:commands/>
< ext:commandextensions/>
< ext:contextmenus>
< ext:add>
< ext:extension name="ItemXmlDisplayExtension" assignid="ext_xmldisplay" insertbefore="cm_refresh">
< ext:menudeclaration externaldefinition="">
< cmenu:ContextMenuItem id="ext_ItemXmlDisplay" name="Show Item Xml" command="ItemXmlDisplay"/>
< /ext:menudeclaration>
< ext:dependencies>
< cfg:dependency>Extensions.Resources.ItemXmlDisplay</cfg:dependency>
< /ext:dependencies>
< ext:apply>
< ext:view name="DashboardView"/>
< /ext:apply>
< /ext:extension>
< /ext:add>
< /ext:contextmenus>
< ext:lists/>
< ext:tabpages/>
< ext:toolbars/>
< ext:ribbontoolbars/>

You must add the empty elements in this order for the configuration XML to be valid.

There are quite a few things to notice about the extension set up; the "name" attribute should receive a unique name and so should the "assigned".

If you wish to place your menu item before an already existing item you will need to know the ID of that item. Unfortunately, Im not aware of any documentations detailing the default GUI IDs so there are two ways to go about finding these.

  1. Find it somewhere in the GUI configuration files or

  2. Which I find easier, is to use Firebug in Firefox:

As you can see, all of the IDs are neatly visible for each menu item element (li).

Next is to specify the menu item details (cmenu:ContextMenuITem) which should include the unique ID, the "name" attribute value is the title the button will receive in the GUI and the "command" attribute which points to the name of the command specified in step 5.a.

Notice the dependency element pointing to the name of the resource group defined in step 5.b.

Lastly, the "ext:apply" element specifies the view in which to show this context menu you created. For the main GUI window we use the view name: "DasboardView".

Ribbon Toolbar Extension

The Ribbon Toolbar is divided into different levels.

A Page ("Home"):

A "Button":

It is possible to add a new button to an existing group, to create a new group or even a new page using the extension configuration.

The following example shows how to add a button to an existing group:

<ext:ribbontoolbars>
< ext:add>
< ext:extension pageid="HomePage" groupid="ManageGroup" name="Item Xml" assignid="ItemXmlBtn">
< ext:command>ItemXmlDisplay</ext:command>
< ext:title>ItemXml</ext:title>
< ext:dependencies>
< cfg:dependency>Extensions.Resources.ItemXmlDisplay</cfg:dependency>
< /ext:dependencies>
< ext:apply>
< ext:view name="DashboardView">
< ext:control id="DashboardToolbar"/>
< /ext:view>
< /ext:apply>
< /ext:extension>
< /ext:add>
< /ext:ribbontoolbars>

To be able to add the button to an existing page and group, we need to know their IDs. Again, the easiest I've found is to simply use Firebug and inspect the HTML. You tell the GUI where to place your button using the "pageid" and "groupid" attributes.

The rest of the configuration is very similar to the context menu example.

Theme Path

Optionally, you can set a theme path for your extensions.

This is done by entering a relative location into the "settings\theme\path" element. Once this is done you will be able to use the theme path in your CSS files, for example:

.ItemXmlDisplay .image {background-image:url({ThemePath}/itemXmlDisplay/styles/icons/xmlicon16.png);}

6. Set up the code correctly.

Now that the extension configuration is ready we need to make sure the code is set up correctly. Create a javascript (.js) file under the Extension folder (for example: "c:\extensions\commands\ItemXmlDisplay").

In the script file there are a few lines of code that must be present for any command to work:

a)  Decide on a namespace for your extension and register it. This is a very good practice to make sure there are never any conflicts with GUI code or other extensions added later:

Type.registerNamespace("Extensions");

b)  Add a constructor to your object:

Extensions.ItemXmlDisplay = function Extensions$ItemXmlDisplay()
{
    Type.enableInterface(this, "Extensions.ItemXmlDisplay");
    this.addInterface("Tridion.Cme.Command", ["ItemXmlDisplay"]);
};

Notice the "addInterface" call, this makes sure your object will extend the "Tridion.CME.Command" interface and allow it to be used as a command by the GUI.

c)  Add the 3 methods a Command object is expected to have:

Extensions.ItemXmlDisplay.prototype.isAvailable = function ItemXmlDisplay$isAvailable(selection)
{
}

The result (Boolean) of this method tells the GUI whether to show the extension.

Extensions.ItemXmlDisplay.prototype.isEnabled = function ItemXmlDisplay$isEnabled(selection)
{
}

The result (Boolean) of this method tells the GUI whether to enable the extension.

Extensions.ItemXmlDisplay.prototype._execute = function ItemXmlDisplay$_execute(selection)
{
}

This method will be called in response to the user action such as clicking the menu item or the toolbar button.

Make sure the resource file configuration element is pointing to the right location. This is relative to the extension's root folder (i.e. "C:\extensions").

7. Setting up the extension's location as a virtual directory in IIS.

Now that your extension is ready to be used, first step to install it is to set up the extension's location as a virtual directory in IIS.

a)  In the IIS console, browse to the SDL Tridion 2011 website.

b)  Under the "WebUI\Editors" directory add a new Virtual Directory, pointing to your extension's location on the disk:

8. Configure extension in the GUI.

the last step is to let the GUI know about your extension. To do this, find the system.config file under "<Tridion_home>\web\WebUI\WebRoot\Configuration".

a)  Make a backup of the file first so you can always revert to the way it was with no extensions configured.

b)  Locate the "<editors>" element and add a new "editor" like so:

<editor name="2011Extensions" xmlns="http://www.sdltridion.com/2009/GUI/Configuration">
  <installpath xmlns="http://www.sdltridion.com/2009/GUI/Configuration">C:\development\Yoav\Extensions\2011Extensions\</installpath>
  <configuration xmlns="http://www.sdltridion.com/2009/GUI/Configuration">Config\extension.config</configuration>
  <vdir xmlns="http://www.sdltridion.com/2009/GUI/Configuration">2011Extensions</vdir>
< /editor>

The editor element  has 3 important elements:

a)  installpath - The exact location of where we created the extension.

b)  configuration -  the relative location of the extension configuration file.

c)  vdir - The name of the virtual directory as its set up in IIS.

That's it. Following these steps should let you start using the extension immediately.

For examples of working extensions and their configuration see my previous post: My SDL Tridion 2011 CTP Extensions Go GA.