Issues

Add Your Own Icons to Umbraco, Automatically

We all know, that some of the most valuable services we can do for our clients, is to make their lives easier when administrating their Umbraco website. One of the little big details in that area is icons. Icons are used throughout the backoffice to guide editors on their quest for getting content on the web.

Umbraco ships with a bunch of very nice icons, based on the free iconset Helveticons. And most of the times, your needs are covered with them. But when you want to go the extra mile, you also want to have more meaningful icons.

Before Umbraco 7, adding new backoffice icons was easy-peasy. You just had to drop png files into /umbraco/images/umbraco (http://www.nibble.be/?p=43) and they would magically appear next to the default ones.

In Umbraco 7, icons are based on icon fonts, and it is also very easy to add new ones. All you have to do is basically to add a stylesheet containing your icon font to the backoffice, through a package.manifest file.

A package.manifest is a file containing a JSON object, you can use to inject stuff into the backoffice with. It is documented here.

You can get your icon font from popular sources like glyphicons and fontawesome, or you could roll your own. Building a font from scratch usually is quite tedious. Luckily there is a few tools that help you. You can create your own icon font at sites like IcoMoon and Fontello. Both sites are pretty easy to work with. You can select your desired icons, and even upload your own. When finished you just click a few buttons, and receive your icon font.

But what happens when you need to update your icon font? You need to go through all these tools, import your icon font, make your changes, export the font, inject it to Umbraco etc. etc. etc.

This is where task runners come to help. With the help of a few gulp-plugins, we can create our own repository of SVG icons, and let Gulp do the heavy lifting when it comes to generating a font, css, and adding it to Umbraco.

Gulp? What's That?

Gulp is a task runner based on node.js. It runs on most environments, and lets you automate boring stuff like:

  • bundling and minifying stylesheets and javascripts
  • creating image sprites
  • compressing images
  • copying files to your site
  • and lots more.

You can find a lot of tutorials on using Gulp (or other task runners) via Google / Youtube etc.

In this article I am going to use the following plugins:

I have set up a folder for my icons, and a template for the generated css. You can look at the git repository here, for sources.

Find or draw icons

I usually look up icons at Iconfinder.com, a great search engine for icons with millions of them. Look for SVG icons, with only one color. They work best in Umbraco. Buy and download your desired icon, and save it in the icons folder.

If you have graphic superpowers, you might also draw your own icons in Illustrator or similar software, and put them in.

Setting up the gulp file

In my gulp file, I have created an object for storing settings. I did that for readability, and also because it would make it easier to just cut and paste into other projects.

The settings object contains a font name, a path to my icons, path to my Umbraco install, path to where I want my icons output, and a filename for my icon fonts css.

var umbIcons = {
	"fontName": "skttl",
	"pathToSvgs": "./BackofficeIcons/",
	"umbracoPath": "../Umbraco.Web/",
	"iconPath": "App_Plugins/BackofficeIcons/",
	"cssFileName": "icons-skttl.css"
}

Generate the icon font

So in my gulpfile, I have a task called generateIconFont. This basically takes all svg files from the path to my icons set up earlier. It then runs through gulp-iconfont-css, to create my css file.

Gulp-iconfont-css can be set up with a template for the css, so I did that to make sure the implementation of the icons was complyant with the Umbraco way of handling icons (the default template wasn't). The css file is generated, and saved wherever gulp-iconfont-css is told to. This is where I use font name, Umbraco path, install path and filename.

After the css generation, gulp-iconfont takes over and creates the font files used in the css. The font files is then streamed through to the destination by gulp.

So there you have it, an icon font with css generated automatically.

gulp.task("generateIconFont",
	function() {
    	return gulp.src(umbIcons.pathToSvgs + "*.svg")
        	.pipe(iconfontCss({
            	fontName: umbIcons.fontName,
            	path: umbIcons.pathToSvgs + "template.css",
            	targetPath: umbIcons.cssFileName,
            	fontPath: "/" + umbIcons.iconPath,
            	cssClass: "icon-" + umbIcons.fontName
        	}))
        	.pipe(iconfont({
            	fontName: umbIcons.fontName,
            	prependUnicode: true,
            	timestamp: runTimestamp,
            	normalize: true
        	}))
            .pipe(gulp.dest(umbIcons.umbracoPath + umbIcons.iconPath));
	}
);

Cachebusting urls

Browsers cache fonts heavily, and since I always tend to have problems with that, I added a task for adding a querystring with a timestamp to all urls in the generated css. This is done with the gulp-modify-urls plugin. As you can see, the task has a dependency on generateIconFont, so if you just run the cachebustFontUrls task, it would run generateIconFont before modifying the css.

gulp.task("cachebustFontUrls",
	["generateIconFont"],
	function() {
    	return gulp.src(umbIcons.umbracoPath + umbIcons.iconPath + umbIcons.cssFileName)
        	.pipe(modifyCssUrls({
            	append: "?v=" + runTimestamp
        	}))
            .pipe(gulp.dest(umbIcons.umbracoPath + umbIcons.iconPath));
	}
);

Getting it into Umbraco

To get custom css into Umbraco, we need to have a package.manifest located in a folder in the App_Plugins folder. So I created a task called generatePackageManifest, that would create a file, name it package.manifest, and add a JSON object with a reference to my css file including a timestamp in the querystring for cachebusting. Again, my settings object comes to help, as the info needed here is fetched from that. The package.manifest files is then saved to my install path.

gulp.task("generatePackageManifest",
	["cachebustFontUrls"],
	function () {
    	return string_src("package.manifest",
            	JSON.stringify({ "css": ["~/" + umbIcons.iconPath + umbIcons.cssFileName + "?v=" + runTimestamp] }))
            .pipe(gulp.dest(umbIcons.umbracoPath + umbIcons.iconPath));
	}
);

At last, I created a task called generateBackofficeIcons. The task has a dependency on generatePackageManifest, which has a dependency on cachebustFontUrls, which has a dependency on generateIconFont. Tasks wont start before their dependent tasks have been run, so it practically starts the whole process from "generateIconfont" until "generatePackageManifest".

gulp.task("generateBackofficeIcons",
	["generatePackageManifest"]
);

And voila, your pile of svg icons, are now available in the backoffice. And should you need to add a new icon to your set, you just dump the svg into the folder and run your gulp task again.

Try it out yourself

If you want to try it out yourself, you can download or fork the source code from Github. Make sure you have node.js and Gulp installed.

Navigate to the folder with the workflow in a terminal, and run the command npm install --save. This will install all the project’s dependencies for you.

When the dependencies have been installed, you can start modifying the config object in gulpfile.js, and dump your icons into the BackofficeIcons folder.

So go ahead, try it out and make your backoffice UX a little bit better. With your own icons, you’ll (almost) never end up choosing the least bad icon for your doc type.

Søren Kottal

Front end tech lead at Ecreo in Denmark. After trying out almost every CMS available (even tried to build a few of my own), I ended up working with Umbraco in 2013, and have never looked back. I love learning new tech, and works hard everyday to make my clients’ experience with their websites even better.

comments powered by Disqus