Wednesday, December 02, 2009 by Niels Hartvig

My challenge today was to come up with a way to provide easier skinning for the blog4umbraco package. Today there's several challenges if you want to get up to speed fast with the current blog4umbraco package:

  • The default skin is old
  • There are layout quirks (such as the comment form doesn't align - yikes!)
  • Alternative skins for blog4umbraco are scattered and there's no conventions
  • Changing a skin requires good knowledge of Umbraco terms such as doctypes, templates and macros. Not easy to get started

The problems above is not unique to blog4umbraco, but a general thing with Umbraco as we like to see ourselves as a framework. This - however - shouldn't prevent us from making it easier to get quickly up to speed for newcomers. And as most people know, once you got something that you can relate to, it's more motivating to dive in.

Bring in the skin

The solution is to create a convention for skins that in the current project benefits blog4umbraco, but over time could benefit other projects such as Warren Buckleys Creative Website Wizard, Runway and the hot new Business Website Starter Pack.

As I'm a fan of keeping things simple and to the point and as we're talking simple skinning (not fancy theming) I decided to keep skins CSS+images only. If the markup is cool, the possibilities with CSS alone is incredible and for more fancy stuff we have the package format to take care of that. So without further ado, let me introduce the new Skin format for Umbraco packages:

What is a skin?

Skins for Umbraco is a zip file containing CSS + images as well as a manifest, a thumbnail and a preview image.

The structure of the zip must be:

  • /thumbnail.png (a 100x100 pixel thumbnail in png format)
  • /preview.png (a 500xYYY pixel preview in png format)
  • /skin.xml (a manifest file containing meta data about you and your skin. See example skin.xml and grab the XSD for Visual Studio intellisense)
  • /css/style.css (your css file. Must be named 'style.css')
  • /css/images/* (images for your css)

User experience

The idea is to host skins in the package repository and make them relate to a specific project. That project can include a new datatype (Skin Browser) which gets configured with some help text as well as a URI that acts as the identifier to fetch skins from the repository. To use skinning in a package all you need to do (once you've got your project approved in the package repo by the evil Umbraco HQ) is to place the Skin Browser data type on the root page of your package content:

umbraco

The skin browser will show you the current skin used and will store the reference to the css file (ie. /css/pixel/style.css). This can easily be used in templates by using the recursive option when inserting an Umbraco field: <umbraco:Item runat="server" id="skin" Field="css" recursive="true" />

When clicking the "Browse skins from Umbraco Package Server" it'll query the repository for a list of skins that matches the project:

chooseSkin

When clicking on the "Use this skin" link, it'll download the skin, extract it and update the css reference (the value of the "Skin Browser" property). When you publish the page you'll then use the new skin.

Nice Balsamiq Mockups - is this vapor?

Well, ehm. The Christmas Calendar manifest say that we can't use more than an hour a day. I've spend three in total (which will make it up for the coming Saturday and Sunday) and managed to make the concept, mockups and formats. But not the datatype - that'll have to wait for one of the coming days. But I did manage to build the server part as well as the submit skin functionality which made me positively surprised of the development speed I gain from Umbraco (nice plug, aye ;-) - but bear with me, I almost don't do implementations anymore).

On our package repository - which runs Umbraco of course - I created a "skins" document type which will be the placeholder for a project (such as "blog4umbraco") as well as a "skin" document type that holds all the metadata:

Picture 15

Using XSLT it was really easy to make a feed that the coming data type can use to fetch the different skins (see the XSLT here) and using alternative templates I can now fetch the list of skins by calling the URL of the project in the repository combined with the alias of my listing template "getskinsasxml":

http://packages.umbraco.org/skins/blog4umbraco/getskinsasxml

Uploading a new skin

I also managed to make a nice little usercontrol that lets you upload your skin (the zip file) and then extract all the meta data and create a new skin as a content object. Using notifications in Umbraco it'll automatically notify moderators to review the submitted skin before publishing it (and thus, making it publicly available in the feed). Again I used alternative templates to make it easy to know which project to associate the uploaded item for. I simply append "uploadskin" to the url and then I know that the current page is the correct skin:

http://packages.umbraco.org/skins/blog4umbraco/uploadskin

One important thing when using alternative templates for something like this that you're responsible for verifying that the alternative template is used on the appropriate type (as alternative templates bypasses the template rules on a doctype). To do this I added a simple check in the Page Load event where I use the nodefactory to verify that the current page indeed has a document type of "skins" (ie. our project placeholder type):

if (Node.GetCurrent().NodeTypeAlias.ToLower() != "skins")
{
    throw new Exception("Can only upload skins to skin repositories");
}

So now we got the skinning infrastructure in place. All we need to do next is building the custom data type using the AbstractDataEditor which makes it easy to build a configurable custom data type as opposed to just using the User Control Wrapper data type which makes it super easy to build a custom data type, but doesn't support configuration.

We also need to look at the markup for the blog4umbraco templates to see if it's as good as it should be. If anyone wants to help with that or help making skins - let us know!

Merry Christmas :)

6 comment(s) for “Blog 4 Umbraco 2.0.2 – skinning”

  1. Gravatar ImageNik Says:

    Amazing! You guys are really kicking butt over there. I can't wait for the CodeGarden this year and REALLY hope I can attend.

    Good work guys. And Happy Holidays!

  2. Gravatar ImageWarren Buckley Says:

    If this can be applied outside of the blog project, to my CWS project, then this is the BEST thing ever.

    Warren

  3. Gravatar ImageNik Says:

    Amazing! You guys are really kicking butt over there. I can't wait for the CodeGarden this year and REALLY hope I can attend.

    Good work guys. And Happy Holidays!

  4. Gravatar ImageNik Says:

    Ooops...Sorry about the double post...

  5. Gravatar ImageHartvig Says:

    @Nik: Those duplicates are awesome. Now we got data when we need to test the coming comment moderator dashboard ;-)

  6. Gravatar ImageDan Says:

    Looking really good. Would be great to incorporate the skin browser with the BWSP (need a short name for that) going forward, so will keep an eye on things here.

    Also willing to lend my front-end-dev hat to reviewing or writing frontend code for the blog template, for maximum "skinnability".

    Dan

Leave comment:


Brilliant umbraco hosting provided by FAB-IT