How to extend the back-office...

... without touching the Umbraco core!

As the winter nights draw close and the days grow shorter, Umbracians around the world ponder the age old question... how can I customise the Umbraco back-office? (Well maybe not, but it is a nice lead-in.)

From a small tweak, to a major UI overhaul, with a little .NET code, it is possible to extend the back-office without modifying the Umbraco core source-code!

Show me, show me

All of the editor pages within the back-office, (e.g. the ones in the main right panel area), expose two events (Init and Load) that can be hooked into. We'll focus on the Init one for now, here's what it looks like:

umbraco.presentation.masterpages.umbracoPage.Init += new MasterPageLoadHandler(umbracoPage_Init);

The best place to hook into such an event is by creating a .NET class, (either in your ~/App_Code folder, or in a separate assembly), that inherits from the ApplicationStartupHandler (in versions prior to Umbraco 4.8 you can use ApplicationBase):

public class MyPlugin : umbraco.businesslogic.ApplicationStartupHandler
{
	public MyPlugin()
	{
		umbracoPage.Init += new MasterPageLoadHandler(umbracoPage_Init);
	}
}

Tip: If you are using Visual Studio, you can use TAB+TAB auto-complete to generate the following stub EventHandler method.

Once you have hooked into the editor page's event, you can then associate a method (e.g. the EventHandler) to access the page itself.

protected void umbracoPage_Init(object sender, EventArgs e)
{
	// the fun starts here
}

The method's first parameter, although marked as an object is actually the instance of the umbracoPage. You will need to cast accordingly:

var page = sender as umbracoPage;

Okay, so now you have access to the editor page object... now what?

Snow me, snow me

Since the festive season is nearly upon us, why not sprinkle a little Umbraco-themed winter snow on your content editors? ;-)

Using a jQuery plugin called Snowfall, we can inject the JavaScript into the editContent.aspx page (via the built-in ClientDependency framework).

Let's walk through the code to show you how; see inline comments for guidance:

protected void umbracoPage_Init(object sender, EventArgs e)
{
	// make sure the page is an umbracoPage; otherwise exit
	var page = sender as umbracoPage;
	if (page == null)
		return;

	// check that the path is allowed
	var path = page.Page.Request.Path.ToLower();
	if (!path.Contains("editcontent.aspx"))
		return;

	// attempt to find/create the ClientDependency loader for the page
	bool created;
	var loader = UmbracoClientDependencyLoader.TryCreate(page, out created);
	if (loader != null)
	{
		// set the custom path for your plugin
		loader.AddPath("SnowfallJs", IOHelper.ResolveUrl("~/scripts/snowfall/"));

		// load the JavaScript resources
		loader.RegisterDependency(998, "snowfall-loader.js", "SnowfallJs", ClientDependencyType.Javascript);
		loader.RegisterDependency(999, "snowfall.min.jquery.js", "SnowfallJs", ClientDependencyType.Javascript);
	}
}

Giving the desired result...

Orange snowfall in the Umbraco back-office
Orange snowfall in the Umbraco back-office

The source-code is available to download here: umbraco-snowfall.zip

...and with that, I leave you with the tender words of Shakin' Stevens:

Snow is falling, all around me. Children playing, having fun.
It's the season, for love and understanding.
Merry Christmas everyone!

Lee Kelleher

Lee is on Twitter as