Blog

How to create a Custom Section in Umbraco 4

Keep the user experience consistant

While creating an Umbraco based application, there is often the need to add extra functionality to the system, especially when we want to create ways to allow the management of business specific aspects or entities.

Instead of creating a separate application, the bespoke functionality should be integrated with Umbraco. Thanks to Umbraco's flexibility, we can extend and adapt the platform in several different ways.

Umbraco's administration area is divided in sections. When we add our own functionality to the platform, we can encapsulate it nicely in its own section. In order to accomplish this, the following steps need to be taken:

Define the section's name and goal

First of all, we need to know what we are creating. For the sake of this article, let's say we want to be able to send a newsletter from the Umbraco administration area. So, we will create a custom section called Newsletter.

Add the section to the database

umbracoApp table

We need to add information to the Umbraco database, in three specific tables. First, we need to add an entry to the umbracoApp table, where the sections are stored. This is what the added information should look like:

Umbraco App _495x 210

Quick explanation about the fields:

sortOrder: Number representing the order of the sections in the interface. We want our custom section to appear last, so we just set the next highest value.

appAlias: Text field representing the identifier of the section, the name Umbraco will use when handling the sections. Make sure it's different from all other appAliases.

appIcon: Text field representing the CSS class of the icon which represents our custom section in the section area. We will add the proper image and CSS information later.

appName: Text field. Don't worry about this field, just give it the same name as the appAlias (you can capitalize it to make it coherent with the other appNames).

appInitWithTreeAlias: Text field. In our example, this field does not have relevance. Just keep it NULL.

umbracoAppTree table

Next, we need to add an entry to the umbracoAppTree table. This enables our custom section to have a top level item, which will be just a folder with the label "Newsletter". We will then add items to that tree with code.

Umbraco App Tree _500x 248

Quick explanation about the fields:

treeSilent: Boolean field. There is only one True in the column, so keep it the same as all the others: False.

treeInitialize: Boolean field. We want the tree to be initialized with code, so we're better off just setting this property to True.

treeSortOrder: We will only be adding the top level node of the tree in this table, so the order of the item is 0.

appAlias: Text field. This should be the same as the section's appAlias in the umbracoApp table added earlier.

treeAlias: Text field. Set it to the same value as the appAlias.

treeTitle: Text field. Set it to the same value as the appAlias. Capitalize it to make it coherent with the rest of the values in the column.

treeIconClosed: The icon to use when the tree nodes are collapsed. Use the same icon as the other trees to make it coherent with the other Umbraco sections.

treeIconOpen: The icon to use when the tree nodes are expanded. Use the same icon as the other trees to make it coherent with the other Umbraco sections.

treeHandlerAssembly: Text field. This is an important field, representing the assembly containing the code to run when the section tree is loaded.

treeHandlerType: Text field. This is the name of the class containing the methods which are executed when the section tree is loaded. This class will be detailed later.

action: No action needs to be taken when the tree is loaded, so keep it NULL.

umbracoUser2app table

Finally, we need to give the Umbraco administrator permission to actually access the section.

umbracoUser2app.png

The user field should be the ID of the main Umbraco administrator (0 by default). The app field should be the same as the appName defined earlier. The main administrator can then give permission to access the section to other users, just like the default Umbraco sections.

Create the section icon

Next, we need to create and incorporate an icon with the section. The best way to accomplish this is by figuring out what files are used by Umbraco to display the default icons and integrating our own icon with those files. The section icons are stored in umbraco\images\tray\traySprites.png. We can extend the file with our own image, sticking to the way the icons are organized. Our updated traySprites.png looks like this:

traySprites.png

We also need to update the umbraco\css\umbracoGui.css file. When adding an entry to the umbracoApp table, we defined the appIcon as ".traynewsletter". We now need to add that CSS class to the /* tray sprites */ section. The new line should look like this:

.traynewsletter { background-position: -18px -594px;}

The background position can be easily deducted by analyzing the other tray sprite classes, as well as the traySprites.png file.

Add the section to the language files

Since Umbraco supports several languages, all language-specific text labels are stored in an XML file located in the umbraco\config\lang folder. For simplicity, we will only make changes to the English language file, en.xml. Within that file, locate the area with alias="sections" and add a new key:

<area alias="sections">
(...)
<key alias="newsletter">Newsletter</key>

Make sure the key's alias attribute matches the appAlias value defined in the database. In this example, appAlias was set to "newsletter".

 

Create the custom pages

Our newsletter module will have two features: sending a newsletter and viewing a list of previously sent newsletters. To accomplish this, we will open Visual Studio and create a new ASP.NET Web Application. We then add two new Web Form pages to the application: sendNewsletter.aspx and previousNewsletters.aspx. Each page should contain the necessary logic and interface elements to implement the features.

To integrate the new pages with Umbraco, we build our application and navigate to the Umbraco root folder. From there, we go to the umbraco subfolder and create a new folder called newsletter. We then copy sendNewsletter.aspx and previousNewsletters.aspx from our application to the newsletter folder. Finally, we go back to Umbraco's root folder and navigate to the bin folder. We put our application DLL here.

using System;
using System.Text;
using umbraco.cms.presentation.Trees;

namespace MyAssembly
{
    public class loadNewsletter : BaseTree
    {
        public loadNewsletter(string application)
            : base(application)
        { }

        protected override void CreateRootNode(ref XmlTreeNode rootNode)
        {
            rootNode.Icon = FolderIcon;
            rootNode.OpenIcon = FolderIconOpen;
            rootNode.NodeType = "init" + TreeAlias;
            rootNode.NodeID = "init";
        }

        /// 
        /// Override the render method to create the newsletter tree
        /// 
        /// 
        public override void Render(ref XmlTree Tree)
        {
            // Create tree node to allow sending a newsletter
            var sendNewsletter = XmlTreeNode.Create(this);
            sendNewsletter.Text = "Send Newsletter";
            sendNewsletter.Icon = "docPic.gif";
            sendNewsletter.Action = "javascript:openSendNewsletter()";
            // Add the node to the tree
            Tree.Add(sendNewsletter);

            // Create tree node to allow viewing previously sent newsletters
            var previousNewsletters = XmlTreeNode.Create(this);
            previousNewsletters.Text = "Previous Newsletters";
            previousNewsletters.Icon = "docPic.gif";
            previousNewsletters.Action = "javascript:openPreviousNewsletters()";
            // Add the node to the tree
            Tree.Add(previousNewsletters);
        }

        public override void RenderJS(ref StringBuilder Javascript)
        {
            Javascript.Append(@"
                function openSendNewsletter() {
                    parent.right.document.location.href = 'newsletter/sendNewsletter.aspx';
                }
			");

            Javascript.Append(@"
                function openPreviousNewsletters() {
                    parent.right.document.location.href = 'newsletter/previousNewsletters.aspx';
                }
			");
        }
    }
}

To keep things simple and coherent, the namespace is the same as the assembly. The class inherits from the BaseTree class, contained in the umbraco.cms.presentation.Trees namespace. Make sure you include the umbraco.dll file in your project's references (you can find it in Umbraco's bin folder). You must also create a reference to interfaces.dll. Further documentation about the BaseTree class and how to create custom trees can be found in the Umbraco website or just searching the web.

Basically, in the Render method we add two nodes to our section's tree, one for sending a newsletter and another for viewing previously sent newsletters. In the RenderJS method, we handle the click on each node and associate them with the respective .aspx pages created earlier: newsletter/sendNewsletter.aspx and newsletter/previousNewsletters.aspx.

To integrate the class with Umbraco, we build the application and copy the resulting DLL to Umbraco's bin folder.

Make sure everything works

Our new custom section is now ready. If we open the Umbraco administration page, this is what we should see:

 

This is our recipe to quickly create our own custom section within Umbraco.

Comments are now closed

If you need more information regarding this blog post please drop us a line.

Contact Us