When you open up the SDL Tridion UI for the first time you are directed to the SDL Tridion tab which shows you a welcome screen, this is sometimes also referred to as the SDL Tridion dashboard. If you open the Experience Manager view, you actually see that the first tab is called “Dashboard”. This dashboard contains useful information for an editor and is even extensible, allowing for a rich user experience on your extensions. Typical things are settings for your own extensions, or perhaps user specific pages (like a custom page, but then tailored to the logged in user) since you have all the UI capabilities available here.
Extending the SDL Tridion dashboard is all about DeckPages, OptionsPanels and ExtendedAreas, basically nothing more than a couple of TridionUserControls or .ascx pages. To explain the possibilities I’ve created an example UI extension, which adds a new option to the SDL Tridion dashboard OptionsPanel (menu item on the left hand side of the dashboard) in both the Content Manager Explorer (CME) and the Experience Manager (SiteEdit). This option loads a DeckPage when selected, and inside that DeckPage you can add user controls through ExtendableAreas. Below is a screenshot of how this extension looks in the CME.

Now let’s start with taking apart the main deckpage, it is a very simple user control which exposes two extendable areas, one for the buttons and body part for the content. The html of this deckpage (an .ascx) looks as follows:
<%@ Control Language="C#" AutoEventWireup="true" Inherits="Example.Controls.DeckPages.MainDeckPage" %>
<div id="MainDeckPageOverlay" class="stack horizontal">
<div class="label stack-elem">
<asp:Label runat="server" Text="Stack Overflow" />
</div>
<div class="separator line stack-elem"></div>
<div id="MainDeckPageButtonsHolder" class="line stack-elem">
<c:extendablearea id="MainDeckPageButtons" runat="server"></c:extendablearea>
</div>
<c:extendablearea id="MainDeckPageBody" runat="server"></c:extendablearea>
</div>
To add the buttons to the page, we need to look at the configuration of the UI extension (an editor extension). Since our deckpage defined two extentable areas, we can now simply add a button under the ext:extendableareas element in the configuration, applying it to the TridionDashboard view (or DashboardView for SiteEdit) and for the control, we reference the id of the extendablearea control (MainDeckPageButtons in this example). See below a snipped of the configuration, adding the first button.
<ext:extendedareas>
<ext:add>
<ext:extension assignid="FirstButton" name="Newest">
<ext:control>~/Controls/ExtendedAreas/FirstButton.ascx</ext:control>
<ext:pagetype></ext:pagetype>
<ext:renderinblock>false</ext:renderinblock>
<ext:apply>
<ext:view name="TridionDashboard">
<ext:control id="MainDeckPageButtons" />
</ext:view>
</ext:apply>
</ext:extension>
</ext:add>
</ext:extendedareas>
The button itself is actually another deckpage or user control, containing a button control in its html. Below the buttons there is another extendable area in which we can place the content for the selected button. This is the same as with the button, but now we apply it to the control with the id: MainDeckPageBody. This user control loads another deckpage which contains our actual content, it does that by adding a deckpage control:
<%@ Control Language="C#" AutoEventWireup="true" Inherits="Example.Controls.ExtendedAreas.FirstButtonWidgetsView" %>
<div class="widgetsviewfilter" id="FirstButtonWidgetsViewFilter" style="height: 25px;">
<div id="FirstButtonWidgetsViewFilter_addressBar" class="addressbar" c:separator="" c:itemsize="20">
<span class="addressbaritem home" c:uri="edu:training" title="First (edu:training)" tabindex="1">First View</span>
</div>
</div>
<c:deck runat="server" id="FirstButtonPages" class="stack horizontal">
<c:DeckPage runat="server" id="FirstButtonPage" SourceEditor="Example" ExternalControl="~/Controls/DeckPages/FirstButtonPage.ascx" PageType="FirstButtonPage" />
</c:deck>
So far we have used 4 different deckpages (user controls) and with that, we have extended the options panel (left hand navigation) and added a button with a content area below it. Inside the actual page for the first button (FirstButtonPage.ascx) there is an iframe in which I load my content to keep this example simple. But basically you can build up this page like any other UI page, with (custom) user controls.
To wire it all up, there is a JavaScript and Stylesheet file available for all user controls (.ascx pages). These files are grouped together using the editor configuration file again. Here is an example of the group for the main deckpage.
<cfg:group name="Example.Controls.DeckPages.MainDeckPage">
<cfg:fileset>
<cfg:file type="script">/Controls/DeckPages/MainDeckPage.ascx.js</cfg:file>
<cfg:file type="style">/Controls/DeckPages/MainDeckPage.ascx.css</cfg:file>
</cfg:fileset>
</cfg:group>
The name of the group is used in the code behind (.cs) file for the MainDeckPage.ascx, to reference its control resources, through this mechanism the JavaScript and Stylesheet files are loaded inside the SDL Tridion UI and made available. The ControlResources attribute is used for this as follows.
using Tridion.Web.UI.Controls;
using Tridion.Web.UI.Core.Controls;
namespace Example.Controls.DeckPages
{
[ControlResources("Example.Controls.DeckPages.MainDeckPage")]
public class MainDeckPage : TridionUserControl
{
}
}
As you can see there is no further C# code for the deckpage, all of the logic is handled in the JavaScript file. I won’t try to explain all the JavaScript code in this article, but will let the code speak for itself. I’ve placed the entire example UI extension on SDL Tridion World, complete with all source code, so you can install it and look for yourself what does what. Feel free to take it apart completely or reuse as a basis for your own UI extensions.
What was most revealing to me, while building this extension, was the fact that it shows how the UI extension framework really works. By adding extendable areas to your own deckpage, you are making your extension extensible itself. It’s directly used for adding the buttons and deckpages for the button content, but you also made it possible for somebody else to extend your extension again.