The previous grid article dealt with how to come up with a CSS strategy when you're working with another visual designer's comps. Now I'd like to discuss doing grid-based theme design for open source content management systems, e.g. Drupal and WordPress. The purpose of this article is to give you an idea of how to approach blog theme design using a grid system. After reading this, you should be able to create a fully-functional grid-based design and HTML prototype that can be coverted into a theme template.
Creating the design grid
I recently redesigned this site because I wanted a layout that provided larger areas for my content. I needed a system that provided me the flexibility to get creative with the layout, but I also wanted to be sure not to lose control of the order and balance of page elements. While the spare layout of my previous design worked well, the new design would be a little more information dense.
For the new layout I used a grid with a simple division of thirds at a fixed width of 801 px. To get to this width, I played around with different sizes that could be centered within a 1024px x 768px browser window with ample white space on the sides. I targetted my maximum width around 800px.
I started by dividing up 800px into thirds and had an approximate width of 267px per third to play with. I borrowed the idea from the MIG design of using a 3 pixel border to separate each division. This odd-sized gutter makes room for 1px vertical border lines with 1px of padding at each side if I need it. I kept sub-dividing the thirds and after a bit of tweaking came up with the grid below. Each little pink box is 1/12 the width of the page (64px wide). 4 of these side to side make up a third of the width, which I would use for normal column of text. 2 or 3 of these side to side would be nice for a narrow column.

Screen shot of the grid (shrunken to fit)
So now I have a grid that could easily be divided into the thirds I needed to make a multi-column layout. This gives me a very simple grid to work with and I don't think I'd need to have smaller grid divisions for blog themes. Next step is to start looking at layout sketches I had in mind and think about how to turn them into XHTML & CSS. The visual design I'm basing this demo on is an old theme I once used on my blog, with a little modification of the graphics and color palette. You can see a screenshot of the old theme (it's the one in the upper left hand corner).
Turning boxes into content areas
To get started, I think about the page elements I want to use. I want the page to have these parts:
- header
- logo
- graphic element
- body
- weblog content
- blog entry
- entry metadata
- comments
- blog entry
- local navigation
- advertisements
- weblog content
- footer
I have some hierarchy of elements established in this list. You probably won't need to jot down a list of elements like this to do a weblog layout, but it helps to show where we're going.
Using the list as a starting point, I start to think about where I want these elements to go on the grid. You can use the grid like a wireframe (page schematic) by selecting areas of content and blocking them out, labeling them as you go.

Wireframe of content areas
Above, I took each of the page elements and blocked them out. We're going to take the wireframe and create the visual design elements for the page and design the layout of the content blocks.

Visual design comprehensive sketch over grid
As I'm doing this design, I realize that I don't actually need 3 grid blocks for the ads, so I use 2 instead. The layout is looking good to me so far, so now I start thinking about how to turn the blocks into CSS.
Turning content areas into CSS elements
Working with grids makes it easier to visualize a strategy for the CSS layout. I start by thinking of the hierarchy of divs that will make up my page wrapper and all of the child divs nested within it. I'll label those in the wireframe to show what I'm thinking.

As you can see, I'm going to enclose the entire page in div#wrapper. The rest is a bit like a sandwich. On the top, I put the #logo and #graphic in div#header. On the bottom, I have div#footer with my copyright info. And sandwiched in the middle is div#main which encloses the 3 column layout of #localnav, #content and #ads.
Next I go about measuring each content block and recording it's dimensions. I'm mainly looking for widths here except for the header, where I actually want the height as well. Heights will, of course, stretch vertically in the div#main. I measure the #header out to be 801px wide by 131px high. In the screenshot below, I show how I get the dimensions of #logo using the Info panel in Photoshop. I do this to each content area, getting fixed widths for all the areas.

Creating the style sheet for the layout
Constructing a shell
When I'm done gathering my measurements, I can start to construct the stylesheet. I start by creating a barebones shell that will look a bit like our wireframe. First I record the main divisions in my CSS file.
#wrapper {}
#header {}
#header #logo {}
#header #graphic {}
#main {}
#main #navigation {}
#main #content {}
#main #ads {}
#footer {}Then I put in all the dimensions and positioning. To test my sanity and the precision of my measurements, I put the grid into the div#wrapper as a background image. The core CSS for the layout is below.
* {
padding:0;
margin:0;
font-family: Helvetica, Arial, Sans-serif;
}
body {
background: #fff;
text-align: center;
}
#wrapper {
text-align: left;
margin: 20px auto;
width: 801px;
height: 801px;
background: transparent
url(grid-unit-boxes-801px.png) 0 0 repeat-y;
}
#header {
margin-bottom: 3px;
}
#header #logo {
float: left;
margin-right: 3px;
width: 198px;
height: 198px;
background: #ccc;
}
#header #graphic {
float: left;
width: 600px;
height: 198px;
background: #ccc;
}
#main {
margin-bottom: 3px;
}
#main #navigation {
float: left;
margin-right: 3px;
width: 198px;
background: #ccc;
}
#main #content {
float: left;
margin-right: 3px;
width: 466px;
background: #ccc;
}
#main #ads {
float: left;
width: 131px;
background: #ccc;
}
#footer {
background: #ccc;
}
/* PIE easyclearing */
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix {display: inline-table;}
/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */Next I start putting the widths (and heights for the #header) I recorded into the style sheet, creating a shell for the site. To make the boxes lay out precisely, I use left floats for columns and the Position Is Everything easy clearing method. If you view a demo of the CSS shell
you'll see that the boxes line up precisely against the background grid. Things are looking pretty good. Now we have to add the graphic elements from the comp.
Completing the wrapper
We're almost done now with the wrapper. To finish off the wrapper we have to cut up the background graphics and tweak the the widths just a little so that our border backgrounds fit around the grid. Take a look at the wrapper with header graphics and borders in place
.
Final touches
It's looking nearly finished now. All that's left is to do the style elements for the HTML inside the major divs. I put in all of the HTML for the template areas. I create the site logo and drop that into div#logo. I add some padding to the columns inside div#main. Finally, I add color and sizes to the fonts. Now you can view the final HTML template
.
Conclusion
Grids are very useful for doing even simple blog themes. They give you a solid system you can rely on to lay out your template and evolve it as needs require.
I showed you how I approach layout and site development for a weblog template and gave you an HTML prototype you can convert into a theme. You are free to use the template in this example, I'm releasing it under GPL. I hope this article helps Drupal developers in some way by giving them a process for approaching their theme designs. Have fun theming!
See also: Cutting and sewing grid-based design: Part 1, working with other people's comps
The Management Innovation Group re-launched their site with a new design. This was the second of two WordPress projects I developed this summer. The first was the Winning Connections site.
The WC site gave me the foundation for learning how to make the most out of WP without having to do any module writing. In the end, these both turned out to very interesting projects for me. And where I used to use MovableType for small client projects, I am now happily using WordPress. I still love Drupal, of course, for the projects that need it.
The MIG project was the more interesting of the two because the design specifications called for a different design template for each section. Quite an interesting problem when you're using a publishing system that is really intended for weblogs. I'm going to discuss 2 things below: 1) how to set your templates up to do section-specific CSS and 2) how to output local navigation.
1) Section-specific CSS
The key to getting the custom templates was to find a way to figure out what section a page is part of. WP gives you an excellent way to establish parent-child relationships when editing pages by simply selecting a Page Parent. But the default sidebar shows the entire hierarchy. The local navigation on both of these sites only shows the children of the section you are currently navigating. To get that to work, I had to do a little scripting.
Using the Page Tools plugin, you can insert a few lines into your template that gets the page's ancestor (top most parent). Then check that variable to see if it's one of your site's top sections, i.e. the links in your global navigation and assign that to the variable $section. If it's not a global navigation section, then assign the post name to the section variable.
// Parent of this post
$parent = page_get_parent_id( $post->ID );
// Fetch parent name for body/section CSS
if ( preg_match("/^[1-5]$/",$post->ID) ) {
// parents
$section_name = $post->post_name;
$section = eregi_replace(" ", "-", strtolower($section_name));
} else {
// children
$sectiondata = $wpdb->get_row("SELECT post_name FROM $wpdb->posts WHERE ID = $parent");
$section = $sectiondata->post_name;
} // endifNow you have a variable to identify the section in the global navigation. I used this variable to target a set of CSS rules that apply to this section, and voila. Instant section-specific CSS.
<body id="<?php echo $section; ?>">
Then in my CSS, I have a bunch of rules for each major element (div) of the page that gives positioning and other style information. So, for instance, the #content div can be different in the #services section from the #content div in the #principals section. Think of it as doing a mini-CSS Zen Garden within one site. All good.
Now, the next step is to determine what page WordPress is serving so you can pass that information to the style sheet as well. This is useful, for instance, in showing an on or selected state for the current page's link in the navigation. You can do this by grabbing the post name and assigning it to a variable:
// body-class for CSS
$bodyclass = eregi_replace(" ", "-", strtolower($post->post_name));Then drop that variable into the body tag as well:
<body id="<?php echo $section ?>" class="<?php echo $csstmp ." ". $bodyclass; ?>">
Then if you assigned CSS IDs to the links in your navigation, you've got a way to target the link as selected or not (e.g. making text color bold and black versus using default link color). Rockin.
2. Putting out local navigation
The next bit of trickery is actually echoing the links for children to output the local navigation. The Winning Connections site is the better example of the two, if you want to see how this works. What is happening here is that all of the children of a main section (a tab in the global navigation) are being displayed in a left sidebar (for local navigation).
This was a little trickier to do and I wish it was handled in a better way by default in WordPress. Maybe someone will point to a better method. My method was similar to the above method for determing what you were looking at. Check the entry IDs to see if we're looking at a global nav parent. If so, do MySQL query to put out links. If not, do a different query to put out local nav links. I won't go over all the details, but here's an example of the code I used to put out the local navigation. Should give you the gist:
// Current browser URL
$dapath = $_SERVER["REQUEST_URI"];
$postsdata = $wpdb->get_results("
SELECT p.post_name, p.post_title, p.ID, p.post_parent
FROM $wpdb->posts p
WHERE p.post_parent = $parent
OR p.ID = $parent
ORDER BY menu_order
");
foreach ($postsdata as $postdata) {
if ($postdata->ID == $parent) {
$class = NULL; $divclass = NULL;
$parent_name = $postdata->post_name; // the parent node
$postdata_url = $base . $postdata->post_name .'/';
} else { // the child nodes
$class = NULL; $divclass = NULL;
$postdata_url = $base . $parent_name .'/'. $postdata->post_name .'/';
if ($postdata_url == $dapath) { $class=" class=\"selected\""; }
// finally spit out the link
$output .= "<li id=\"menu2". $postdata->post_name ."\"><a href=\"". $postdata_url ."\"". $class .">". $postdata->post_title ."</a></li>";
} // end else
} // end foreach
// echo the list
echo $output;None of this would have been possible if it weren't for the efforts of others to make WordPress extendable. It's the same experience I have in using Drupal modules. People who contribute their ideas or code to make open source software better are cool. They're the ones that make some of these projects possible to implement with little effort.
Necessary plugins
These are the plugins I had to use to make these sites work.
- Page Tools -- for retrieving the highest ancestor (parent). This was useful for establishing what section is being viewed and then inserting that section name in the body tag as a CSS ID.
- The Excerpt Reloaded -- perfect for customizing the appearance of excerpts.
- wp-cache -- not that this site needs it, but excellent for taking the load off your server and saving you in case you get slashdotted for some reason.
A plugin to modify the style of WordPress administrative interface.
FeedWordPress is an Atom/RSS aggregator for WordPress. It syndicates content from newsfeeds that you select into your WordPress blog; if you syndicate several newsfeeds then you can use WordPress’s posts database and templating engine as the back-end of an aggregation website.
We launched the Winning Connections site, my first project using WordPress. It's great to work on small projects like these that use weblogs for pushing news and marketing information. This kind of site development gets easier and easier with the evolution of weblog systems that can accomodate both pages and weblog entries as Drupal and WordPress do naturally.
I'm happy things are back to normal on this site after yesterday's permissions headaches. But for a good part of yesterday I was ready to chuck my beloved Drupal for something else. All day yesterday all I could think was, "life's too short to be wasting on tinkering with web publishing software." Alas, it was a single module that was the culprit and I'm back, but not without coming very close to leaving Drupal.
Casting about for a quick fix, I downloaded WordPress last night and migrated my blog over to it. Was really quite simple. I found this process documented on vrypan.net. Worked pretty well, but his process didn't work for me on the first try. I modified his process and SQL statements a little to make this work for my system.
The first time I ran these SQL statements, a bunch of my node categories weren't carried over correctly. To correct this, I flattened my hierarchies by making all the terms have a parent of 0. This kept the categories attached to each node correctly.
Then I noticed that comments were all entered as anonymous. So I modified the SQL statements for the comments table a little so that commentor name, email and homepage are carried over as well.
Here's my new process:
- Backed up Drupal database using mysqldump:
mysqldump -u [username] -p -h [hostname] [databasename] > drupal.dump
- Loaded dump file into a new database:
mysql -u [username] -p [newdatabasename] < drupal.dump
- Flattened taxonomies in MySQL:
UPDATE term_hierarchy set parent=0;
- Downloaded and installed new Wordpress system
- Configured the new WordPress system to use the new database that is now loaded with my backed up Drupal database.
- Ran these SQL statements
DELETE FROM wp_categories ;
DELETE FROM wp_posts;
DELETE FROM wp_post2cat ;
DELETE FROM wp_comments ;INSERT INTO wp_categories(cat_ID,cat_name, category_nicename, category_description, category_parent) select term_data.tid, name, name, description, parent from term_data, term_hierarchy where term_data.tid=term_hierarchy.tid ;
INSERT INTO wp_posts(
ID, post_date, post_content, post_title, post_excerpt, post_name, post_modified
)SELECT nid, FROM_UNIXTIME(created), body, title, teaser, concat('OLD',nid), FROM_UNIXTIME(changed) FROM node WHERE type='blog' OR type='page';
INSERT INTO wp_post2cat (post_id,category_id) SELECT nid,tid FROM term_node;
INSERT INTO wp_comments (
comment_post_ID, comment_author, comment_author_email, comment_author_url, comment_date, comment_content, comment_parent
)SELECT nid, name, mail, homepage, FROM_UNIXTIME(timestamp), concat('',subject, '
', comment), thread FROM comments ; - Done
The results were pretty good. I would have to create another set of SQL statements to move over the weblink tables as well. I started exploring the WordPress administration and began to feel the satisfaction with working with a separate administration panel again (boy do I wish that were still an option with Drupal).
Then I started my superficial exploration of how things worked. Things seemed pretty cool. Creating themes and installing modules/plugins are probably where I spend the most time modifying a blog system. I probably wouldn't be put in the largest category of bloggers -- those who just install and publish. I customize and configure a little. I'm not a developer either, but I can modify perl and php code or create my own very simple modules/plugins. So I'm in some middle category, which helps me understand the needs of novice bloggers and those of developers when it comes to using blog systems.
Theme administration looked easy and was not abstracted in WP. The basic idea was that you copied or created a new writable theme directory in wp-content/themes/ and put all the theme files in there. The administrative interface provides forms for editing the files. Not very sophisticated, but simple enough.
The first thing I did was look through these PHP files and try to figure out what I could do there. I specifically wanted to see how the Kubrick theme was putting out the catgories. In the sidebar template I found a function call for list_cats(), a function that took 17 arguments. Yikes. Then I went poking around for it in docs and found some documentation. All of the Template tag docs were great. I found their docs to be pretty easy to explore, but their set of documents is quite smaller when compared with the Drupal Handbook and the separate Developer's Documents. It's interesting to compare the two. The doxygen documentation and the new drupaldocs site make it easy to find your way to known items, but this particular tool for searching documentation is very much for programmers.
I'm sure there are a lot of Drupal users like me -- regular bloggers who don't want to know too much about what's making things work on the backend, but who also need to be able to do a little bit more than display a reverse chronological diary. I find that at difference times I need ease of use in finding readable documentation to figure out how to do things. But at the same time, I'm willing to give up some of that ease of use for more flexibility and functionality even if it means working in a more cryptic environment.
This all reminds me of a usability dilemma I've come across in the past. People will often sacrifice a little ease of use for functionality, price or whatever makes it worth the loss of ease. It's why a lot of people may decide on a sub $1000 PC laptop rather than a Mac 'Book. You determine the point where you give up one for the other. And that's where I am. I so desperately crave ease of use and management. But, I don't see a super simple blog package out there that let's me do the things I want to do, how I want to do them. (Realize that the "how I want to do them is what may separate my choice from yours.) Specifically, as you may have noticed, I get geeky with information description (taxonomy use) and I've got a personal weblink directory that's probably larger than the average blogger's bookmark list. Today it's got 734 links in it, and every one is categorized using the same subject taxonomy that I use to describe my blog entries. And there are RSS feeds for each category. It's pretty damned cool that I can do these things I consider simple, but necessary by just using built in functionalities and in this example, two easy to install optional modules.
This is the stuff that helps with my professional development. Personal knowledge management for me comes in the way of using my subject-classified weblog and linklog to retrieve and synthesize what I learn, observe or use. Drupal has made this possible, but I could have easily, although perhaps more cumbersomely done this in any other tool. But, after having used Drupal for the last 4 years, I think I'd find any software lacking if it didn't have the rockin taxonomy guts to tie it all together out of the box and the modules to make more sophisticated browsing and retrieving also possible.
And finally, the real thing that made me realize why I want to stick with Drupal was only revealed after I actually did look a little bit more at how WP was architected. I thought it was put together very much the way I might put a small application together right now. You know, I actually did roll my own set of light publishing scripts once for a site I did back in '99. It's an experience worth undertaking. But after working with Drupal I am able to appreciate the way things are architected there. Often I learn new ways of doing things just by figuring out how they're done in Drupal. I have the same experience at work where I figure out how some of the Perl stuff our programmers make works so I can use that knowledge in writing the little Embedded Perl pages I write. I think this is ultimately the reason I want to stick with Drupal for now. The idea of working with something that will be a challenge and will force me to learn to do things more elegantly and efficiently is somehow more attractive than using something that simply works and is usable but doesn't do much in the way of changing me more profoundly.
This has been a really odd blog post. I started out in some respects documenting how to migrate away from Drupal and in the end I'm starting to tell you why you wouldn't want to.
I really don't think it matters much what anyone chooses to do their personal publishing. I applaud anyone who tries to do personal knowledge management with software, and open source blog tools in particular. In the end, the choice becomes religious. You choose the one that you believe will deliver what you need, with the features and requirements you can work with, and the level of usability you can tolerate. After my brief taste of the other side, I'm back again to Drupal. It was a 1 day departure. Sometimes you have to go away to find your way back home.