Diazo theme inheritance

written on 2013-02-06

With old style theming in a package you could base your themes on Sunburst or classic. Creating themes based on frameworks got me to do the theming on the content side and then move the complete body over to the theme side. After several variations of one type of framework the constant duplication of resources, made me realize I needed some form of inheritance for this type of diazo theme.

Check out diazotheme.frameworks and diazotheme.bootswatch for the result.

Why theme on the content side?

The Plone html structure has been set up with a sensible content order in mind. This is the same for most popular frameworks. They have also been created with reusable blocks of of tags and classes, like Plone. They have grid systems, typography and JavaScript based on those reusable code blocks. And though the execution between different frameworks and Plone differs, the overall idea is the same.

Diazo is a great tool when you want to change similar html structures across a lot of templates. With only a few lines of code in the rules file you can change al the submit inputs into buttons. If you would want to do that in an oldstyle theme you would have to change dozens of templates. There was a question on the Plone UI Team mailing list about making it easier to plug Plone into some popular frameworks. This made me think that diazo would be the tool to do it. You don't want to redo a complete template set in order for the html to fit with another framework. By switching out Plone's reusable structures with the framework ones on the content side, you keep the templates intact but turn the html into what Plone would look like in another framework.

Queue Bootstrap

I figured I'd try and start with the most popular kid on the block and theme me some Bootstrap. Not looking around whether or not anyone had done it already. Starting off I was just moving Plone content into the example templates they have in their documentation. But then I got to the grid system. Since Bootstrap already has div.row and only uses a different syntax for the columns within, the best way was to swap out the div.cell with the Bootstap divs.

One thing led to another and I was starting to see swappable structures all over the place. Several iterations and themes later (I was also working on some easy starter themes, which of course also had to have a Bootstrap one, not having seen the example theme...), I was duplicating the same framework files all over the place. Not only that, but also huge chunks of rule file. Being human, in all that copying some sloppiness will occur and I noticed that there is no problem using resources from other themes. I also ran into diazotheme.bootstrap (which was also the name I was working under) which uses XIncludes to move some recurring rules to a separate file. These two "discoveries" are the basis for diazo theme inheritance or using a parent themes resources and rules.

The premise for framework themes

I ran into Bootswatch, which gives you a load of new stylesheets that work with Bootstrap, different themes if you will. Every Bootswatch theme needs 80% of the Bootstrap theme's resources and 99% of its rules. What did I want from a framework theme:

The setup

Parent theme

Create a package (I tend to use paster create -t Plone diazotheme.*) and copy in the framework files. Some frameworks come with an html example, for others you need to find it online, also copy that in and then do not touch them anymore. I tend to want to change directory names and structures to my preference, I DO NOT DO THIS FOR FRAMEWORK FILES. If you feel you need other resources outside of the framework resources, keep them separate from the framework resources and out of the framework directories. Do think twice before adding any extra resources, wouldn't they fit better in a child theme?

Then setup the diazo theme, by adding rules.xml, preview.png and manifest.cfg. Do the theming until you think the rules are done. Chop the rules up into sensible blocks with XIncludes and move them into separate files. Think of likely candidates for being done differently in a child theme while keeping the rest of the rules intact. One block you will at least want is the framework stylesheets, because most likely a theme will override them. The easiest is to have your rules file only have rules you are certain will never be needed in a child theme. And even then have as little rules in there as possible, the rest of the rules in XIncludes. I tend to copy the complete rules file into a child theme and then remove and change what I need. Removing XInclude one liners is easier then code blocks.

Child theme

Create a package (I tend to use paster create -t Plone diazotheme.*), add the unique resources (or start creating them later on) and setup the diazo theme. Add a preview.png and manifest.cfg. Copy over the rules.xml and start tweaking them.

Remember to add the framework theme as a dependency to the child theme.

You can see a working implementation in the diazotheme.frameworks (parent) and diazotheme.bootswatch (child).

Pros & Cons