Gerry McGovern makes excellent observations on CMS feature simplicity and sustainability of use in his article, "Complexity delivers short-term gain but long-term pain". He bases his argument on the "feature fatigue" phenomenon, cited by researchers at the Smith School of Business, which claims that most people focus on features when buying a product not on usability. The study notes:
"Consumers give more weight to a product's capability benefits and less weight to a product's usability before they use the product than after they use the product-despite the fact that a product's usability strongly influences their satisfaction with the product."
McGovern argues that the same can be said of CMS and that buyers of CMS should beware this tendency to be wowed by features over usability.
Feature fatigue and CMS
The Smith study focusses only on pre-purchase behaviors and perceived satisfaction during use. They say that it's only in the actual use of a technology that you can determine satisfaction. I don't know if the study mentions any data about sustainability, but the article on the Smith study implies that when users of consumer electronics are confronted with complex, unfriendly technologies they may eventually abandon them, as they say "chucking it in frustration".
I'm a believer that satisfaction is a good determining factor when it comes to sustainability and that another statement would also be true. If users are confronted with an easy-to-use technology, they will be more likely to continue to use it. You'd have to prove that, of course and I don't know if it follows logic to simply say that since unusable technology has one effect, that usable technology should have the opposite effect. But it seems obvious. I would go further to say that an even worse outcome is that if a given technology is necessary for running your business and that technology perceived as a user-hostile experience, that it will interrupt the normal flow of one's work and slow the company down.
Putting the feature fatigue concept in the context of enterprise CMS seems a logical analogy. However, there are variables in corporate environments that may make it difficult to make a clean-cut transition out of existing systems unless there is understanding from the top of what pains users lower down the chain. The concept of user satisficing—the tendency to select the first option given that can work for the situation rather than the "optimal" solution—is one phenomenon that contributes to the complex issue of use and sustainability. People make do with what they have.
That leads me to wonder what the path to change is when people have become accustomed to using complex software that is difficult to use? What factors exist in this situation? Are people on the low-end able to communicate upwards what they experience in terms of dissatisfaction? Is that information received? Can it be used to evaluate current technologies as successes or failures in supporting sustainable information management processes?
It may seem difficult to change in the direction of usability and satisfaction when you've invested heavily in technologies that are the cause of your pain. Moving away from a family of products may feel disruptive if bulk licenses are already paid for and staffed to support those specific technologies. But the bottom line for decision makers is that the payoff comes in business intelligence, the ability to make sound decisions based on experience. That past and ongoing experience is retrievable because your employees capture it in an easy to use CMS. Let's look at a few dimensions affected by ease of use to illustrate why it's an important element in affecting a company's bottom line.
- Ease of use leads to satisfaction with CMS and sustained use
- Sustainability leads to a richer information repository (CMS)
- Rich information repositories lead to more meaningful information mining
- Rich information mining leads to more informed decision making
- Better decision making leads to fewer dollars lost and more business opportunities
In the end, it's about money. If you believe that ease of use leads to making more money, you start to take it seriously. We need to see some studies demonstrate that. But what we're talking about here in terms of actions is simply ensuring the satisfaction of your key asset, your knowledge workers. To put it simply, if employees are happy to keep adding reusable knowledge to the business, the business benefits in explicit terms that may be traced back to the information capture. If you want to prove it, it would seem that if you can capture longitudinal data to compare the flow of knowledge into the CMS with ease of use and satisfaction dimensions, then you can provide some insight into return on investment.
Evangelizing simplicity in the enterprise (the software user's story)
So the question for corporate decision makers feeling the pain of complex and unusable technology becomes, "how do we sell our company on the idea of usability as a strategic move?" If the revolution can't happen from below, the vision has to come from above. But the people above need to be convinced through the experience. Sometimes, the perfect pitch can go nowhere without concrete examples. The way you sell it is by demonstrating value through use.
First, point out success stories. If you read and agree with 37 Signals' popular ebook "Getting Real" then you don't need to be convinced that simplicity and usability can equal dollars. They focus on simplicity because it ensures satisfaction in 95% (or some high number like that) of their customers. That 95% uses 37 Signals' customers comes to 37 Signals because the specific solutions they provide are the antithesis of what they've used for processes like project management and collaboration. They want small, simple and efficient and they leave satisfied that they can get in, do what they need to do to collaborate or organize their stuff and get back to work. How's that for a productivity pitch?
Second, prove the concept. Set up real world demonstrations. Put it before people and show them how it works. Remove obstacles and make it easy. Provide an open testing period, do a super-short training screencast or cheat sheet and then let your staff have at it. You can set up pre-determined areas for activity and open up the system for personal information management. This way, users determine it's usefulness. But most importantly, they get to try it out and experience an environment that makes their information management process simpler and more satisfying.
I've been privy to demonstrations where vendors allow some testers to use their software beta in order to build up some excitement around their software's release. Vendors get potential customers to start experiencing their sofware ahead of releasing. And if they create an environment of open communication they also get to establish a relationship with their customers. Other benefits include word of mouth recommendations, feedback on improvements,and if their software is well received, better assurance of its use. All of this before they even release the software commercially. It should go without saying that a vendor would benefit greatly from beta tests.
As a CMS customer, a company could follow this lead and do the same thing, testing vendor software in an enterprise environment. Set up a private testing period for a select set of users and create an open environment of communication around it. Let the feedback stream in and use it to build momentum around the technology. If it's received as a simpler, more usable way of doing business, you're on the right track. Use the feedback to improve how it integrates with your processes. Use that feedback to get better usability improvements out of your vendor. When you're happy that your test users are satisfied with the experience, release it to the enterprise and keep the communication environment open.
Using simplicity as a design strategy (the vendor's story)
And how do you employ usability as a strategic factor if you are a software vendor? First, believe that ease of use should lead to satisfication with your product, and that usability in turn leads loyalty to the company in terms of renewals. I hate to sound like a Mac Fanboy, but the Macintosh Operating System is proof of that. Google search may be proof of that as well.
Consider that usabilty and simplicity is one of the key factors making weblogs attractive as replacements for complex CMS in the first place. It's the main reason that many corporates took the leap and tried this new thing, blogs as the 99 cent KM solution. Many were likely comparing the simplicty of blogs to failed KM solutions they bought. Use that knowledge to your advantage. Simplify your experience to show customers a better way.
When the software you have developed has evolved over time into a more and more complex environment, are you out of luck? Of course not. You step back, take a look at the customer's experience of using the software -- everything it evokes as they use it. Find ways to make it easier. Simplify where you can. Remove obstacles. Do whatever you can to take the pain away. Guage satisfaction constantly by listening to feedback and factor it back into improving the user experience with your software.
It may not happen over night, but making your software usable is a worthwhile goal. Overall, it's not impossible to change in the direction of simplicity. More concrete advice is to break the process down into smaller steps.
- Cement your strategy with user experience and usability as a keystone.
- Understand your users by creating personas that describe who your users are and what their goals are. Focus design on them (persona-based user-centered design).
- Describe the use cases that apply to personas.
- Describe specific scenarios for each use case above. What types of actions would they take with your software in order to achieve goals?
- Prescribe improvements to the user experience that match with the expectations found in the use case scenarios. Suggesting flow and interaction improvements. Suggest usability improvements to elements of your user interface.
- Validate the implementations and test against real people.
- Use the feedback to validate information about the design process you just underwent. Iterate.
That's all there is to it! Well, no, there is a lot more to it, but this is a start.
Food for thought
The Smith study and McGovern's article should be enough food for thought. It's our job as users and makers of software to just understand that satisfaction can be improved when software, however complex or simple in features, is easier to use.
Applying the Smith study's consumer electronics research is just a start I think. It would be valuable if someone did longitudinal studies that track satisfaction and abandonment or sustained use in other areas, especially with regard to personal and enterprise productivity and content management software.
Someone asked me how I display different header images on urlgreyhot depending on what section (corresponding to the global nav tabs) you are viewing. My solution might not be exactly simple or the best way to go, but it works. Here are the steps:
1) I use the path_auto module to create URLs depending on either node type or vocabulary. So in my pathaoto settings I have weblog entry urls created as "weblog/[title]" and everywhere else the URL is either created manually or built based on the category (taxonomy term) so the services section urls are "services/[page title]".
2) In the PHP-Template theme, I do a regular expression check to see what the path is and assign a variable depending on what section we're in, e.g.
$dapath = $_SERVER["REQUEST_URI"];
if (eregi("/personal/services*.*",$dapath)) {
$sect = "services";
}3) I put that variable in the body tag:
<body id="<?php echo $sect; ?>">
4) I place an empty div in the page, which will be the placeholder for header image:
<div id="section-header"></div>
5) I put a rule in my style sheet to display the appropriate image depending on what section is being displayed:
#services #section-header {
height: 131px;
background: #fff url(bg-sect-about-me.jpg) top right no-repeat;
}This is also how I display a selected tab in the global navigation. The idea there would be to make each link in the nav have an ID, so you can then apply a CSS rule for #services #services-menuitem, for instance. It's a serviceable method. Do you do something similar in a perhaps more elegant way? How do you do it?
Here's a tip that only an information geek would care about. If you've ever looked at my taxonomies, you'll know that I describe nodes by facet, e.g. file format, person, subject. Years ago, in another version of Drupal, I used to show terms applied to each node by facet, but with the upgrades and changes to the taxonomy module, I gave up trying to keep that up to date. Luckily, I found in the PHP-Template documentation, that someone posted a snippet for sorting/displaying terms by vocabulary. So I'm using this snippet to display my terms by facet again.
Here's a screenshot of terms in action:

Like I said, that's the kind display of metadata that only a info geek would want. But I think it also demonstrates to people new to Drupal the kind of description/categorization of content that might be useful in different environments, e.g. a corporate intranet.
So to do this, use the following code in your node.tpl.php (snarfed from drupal.org):
<?php if ($terms): ?>
<?php /* sort taxonomy links by vocabulary 27 */
$terms27 = taxonomy_node_get_terms_by_vocabulary($node->nid, 27);
if ($terms27) {
print '<div class="terms">Forums: ';
foreach ($terms27 as $key => $term27) {
$lterm27 = l($term27->name, 'taxonomy/term/'.$term27->tid);
print $lterm27.' - ';
}
print '</div>';
}
?>
<?php endif; ?>You would repeat that code block sandwhiched between "if($terms) ... endif" for each set of facets you want to display.
Aarrr, matey. Here be a tale of a blogging practice that makes ye look like a bilge rat pirate

As a rule, you should periodically check referrer logs. Usually it's good practice because you find out who's linking to your work. But once in a while you'll also find a site that's either copying your content outright without permission or that's embedding links to your media (images, MP3's, etc.) in their site and essentially pirating your bandwidth. This morning I found a site that was embedding links to my images in their page. Avast! The image on the right shows a bit of their page and how I'm replacing images (See the "Revenge" section below to see how this works).
My site publishes complete entries in its RSS feed. Because of that, other people's web-based aggregators are able to republish my content in its entirety. In the best case, a blogger uses a web-based aggregator to watch feeds and post the ones they like, excerpting the entry. In the worst case, they republish your entire entry without attribution. I don't know what this site owner was doing, but I noticed that their blog was basically aggregating other people's posts. There doesn't seem to be any original content. But in my case, they didn't excerpt, they re-copied my entire blog entry verbatim. What pisses me off is it looks like they wrote the article.
I suppose it's partly my fault for putting full entries in my RSS feed rather than excerpts, but I do this so that people can read my blog in their aggregators without having to actually go my site. This is the downside, I suppose. Web-based aggregators will republish whatever they get.
I take me revenge
To play with them a little, I now replace images referenced from another site with a STOP image. I hate to have to do this, because it messes up the images for legitimate aggregators. I suppose you could be really malicious and post a hardcore porn picture in there instead to make thinkgs look even worse. I'm not that malicious.
You can do the same thing if you find that someone is pirating your media. Using altlab's examples for dealing with bandwidth theft, I modified the .htaccess file on myserver to include these lines.
RewriteEngine On
RewriteCond %{HTTP_REFERER}
!^http://(www\.)?urlgreyhot\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule \.(jpe?g|gif|bmp|png)$ img/pirate.png [L]
To use this code on your site, replace the second line with your domain and modify the fourth line to use the path to your stop image.
I thought about this a few minutes. Because I don't want to do this to everyone, I can use the code below as a method to block from that domain only:
RewriteCond %{HTTP_REFERER}
^http://(www\.)?badsite\.net/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule \.(jpe?g|gif|bmp|png)$ img/pirate.png [L]
To use this code on your site, replace the domain first line with the domain of the bad site and the change the third line to use the path to your stop image. Take that, ye scurvy lubber!
Yo ho! Here be Mr. Krabs bit of advice to ye
This is why you should always look at your referrers! Be smart about RSS aggregation and blogging. If you are going to use an RSS aggregator to feed your blog, be sure to excerpt and ALWAYS link to the original article and attribute the author.
Update
Moments after doing this, they must have seen the replaced image, so they removed the copied entry from their site.
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
What kind of grid article is this?
Good question. After I blogged that I wanted to write this entry a few weeks ago, I started wondering if it was worth it since more appropriate people (visual designers) have written about grid-based web design already. Few people, however, seem to have talked about their actual process of getting a comp, cutting up its graphics and using it to produce actual CSS. As you may know, this blog is all about exposing my processes. So I thought there might be some value in writing about it.
As a site developer I often have to produce web graphics from other people's design comps, a process that involves slicing up layered Photoshop files. When I'm lucky, what guides me is a visual designer's grid system. A few years ago I would then take these grids and turn them into tables. The technique and math of doing CSS layout today is bit more complex than doing HTML tables, but it's also simpler in terms of separating presentation from content.
In this article I'm going to discuss the steps I take when measuring and cutting a comp layed over a grid and turning that data into CSS. The point is to demonstrate the steps to site developers who are new to grids. If you are already doing grid-based site development, this is not for you. I'm writing a second part to this article that provides more step-by-step instruction to using grids to design a site theme and producing the XHTML/CSS to match the visual design.
First a disclaimer. This entry is not meant to instruct you with regard to the design of grid systems. If you need an introduction to designing with grids, the literature below should give you what you need.
- Articles
- "Five simple steps to designing grid systems", Mark Boulton — discusses the practice of designing grid systems and ultimately applying them to web layouts.
- "The Funniest Grid You Ever Saw", Khoi Vinh — discusses the use of a grid system in the Onion.com redesign.
- "Thinking Outside the Grid", Molly Holzschlag — offers a differing opinion about the restrictiveness of grids in web layouts.
- Books
Sketch, measure, cut and sew: An example deconstructing a design grid
Here's a quick example to show you what grids do for you and how to use them as a site developer. You'll forgive the headings, but a friend has gotten me into watching Project Runway lately. The analogy to me is obvious. When we design, we strategize, architect and then produce. Not very unlike making a dress, no?
Sketch
On a project I completed in summer 2005, a visual designer gave me a few comprehensive sketches for the fixed-width layouts he wanted to use on their site. The comps showed a unique layout per section. A simple grid system was used to lay out the pages.

Grid system applied to home page
In dress-making, this would be the part where someone sketches designs and drapes fabric or paper over a dress form or mannequin to prototype the design concept. In our case, the grid is the mannequin and the comp is the pattern. I was surprised by how easy my job of planning the multiple layouts was because of this simple grid. The next step would be to identify where those divs would go and how to size them.
Measure
I worked with the designer to come up with usable widths for his grid based on browser resolutions we would expect from prospective users. He ended up providing me a final version of the grid that maxes out at 767px wide. This gave him enough room to be usable for browsers at 800 x 600 pixel resolution. He finally delivered a document to me that looked like the figure below (scaled down to fit this this blog entry). This was to be the grid system used in all of the layouts for a client web site. If you're playing the sewing game along with me, again this is the paper for our dress pattern.

Grid system
You'll notice that this simple grid specifies widths for columns and heights for rows. The designer gave me a set of comprehensive sketches that were drawn to grid. I was a little apprehensive at first, of the preciseness of the comps, thinking that positioning fixed-sized boxes might be tricky in some places. But the layouts are not that complicated really. Only a few key boxes needed to be precisely positioned at vertically locations. The main content areas would of course stretch vertically as needed. The trickiest part was dealing with font size increase in the narrow navigation links (system text) of the header. The logo was not a problem because I was using image replacement for that. In the end, I was excited by the challenge and set out strategizing how I'd architect everything and started measuring.
Cut

Home page: Identification of style elements and measurements for divs
Using the grid-based design comps provided me with units of measurement that I could easily turn into divs for the style sheet. I figure out the areas of content in the same way I would work with a wireframe to block out content and graphics. I come up with a naming scheme for these blocks and turn them into CSS elements. Next, I measure out the blocks of content or graphics in the designer's comp and record measurements for my style sheet.
I don't usually do all the documentation of things like above, but if I was working with a large team, e.g. handing off pieces to another site developer, these documents would be very useful. What would be even more useful is a method to automate some of this process of wireframing and CSS element measurement without using something like Dreamweaver.
Sew
One of the requirements of this site was that the owners have the flexibility of using a unique layout in each section (each link in the global nav). Using a method I gleaned from Doug Bowman, I tell the content management system (CMS) to change the id applied to the body tag depending on what section the page is in. This targets a set of layout rules specific to the section it's in. To provide an example, the "Principals" section uses this <body id="principals"> while the "Contact" section uses this <body id="contact">. Each section uses the same grid but their layouts differ from one another.
The result would be that we produce different layouts for each layout type (section in this case). So we could modify the position of the page title area for example like so:
#principals #title {
position: absolute;
left: 0px;
top: 97px;
width: 189px;
height: 189px;
background: #000;
}
#contact #title {
position: absolute;
top: 96px;
left: 96px;
width: 96px;
height: 96px;
background: #E50530;
}
I'm using the same markup in both XHTML files, but because the Principals section uses the <body id="principals"> tag, it gets that first set of rules for positioning the #title above. The #contact section gets that second set of rules.
Now to show how we sewed up the final product. The grid is ghosted over screenshots of the two layouts I mentioned above. You'll notice how the page titles are positioned differently, following the CSS rules above. I was very satisfied at how precisely I could get the final pages to look like the sketches using CSS.

"Principals" page design layered over grid

"Contacts" page design layout layered over grid
Pretty simple process, but wow, that was a long example. I won't go into the details of that site's CSS, but the next part of this article will talk a little about the redesign of my site, getting from those comps to markup and CSS and how you can use the same process to plan and implement your site theme/skin files.
See also: Grid-based design: Part 2, Designing blog theme templates.
Today's tip is simple, but potentially very useful to someone. One of the things you might notice if you visit some of the popular commercial blogs is that they sprinkle ads throughout their list of blog entries. For example, on your blog page, you might have a row of ads after the 2nd and 6th blog entries or something. Tweaking your ad placement is one sure way to increase your click-throughs. Doing this in Drupal is easy.
In your PHP Template theme, the node.tpl.php file controls the display of your nodes listing (e.g. node/ and blog/ pages). If we wanted to put an ad after the 2nd and 6th blog entries, we can put this code at the top of that file:
<?php if ( !$page && ($id == 2 || $id == 6)) : ?>
[replace this comment with your ad code]
<?php endif; ?>The first part of the if statement (!$page) checks to make sure we're not looking at a single node page, e.g. node/view/1. The second part ($seqid = = 2 || $seqid = = 6) says to apply this code only to the 2nd and 6th entries on the page. Just change the numbers to wherever you want the ads to appear. Then drop your Ad code (e.g. from Google Adsense) in to replace the comment. To see what this looks like, check out the Weblog page on this site.
Note: According to http://drupal.org/node/46209 $seqid becomes $id in 4.7
Since redesigning this site, I've been getting a ton of requests for Drupal theme design. Most of the projects are too small for me to take or require too much work for the amount of money people have budgeted. So to help people who are new to doing theme design with Drupal, I'm going to start a series of tips on getting more out of your Drupal themes. My focus will be on using the PHP Template engine for my examples because it's the best option for flexibility of your theme design. I should note that not all tips will be theme specific, however. This first tip is really about re-using content blocks in pages.
The portal model
Some of you may be familiar with the concept of portlets inside portals like Oracle Portal or some such. Portlets are little windows of content that you insert into a portal page. So you might have a page on a topic, e.g. Human Resources in your portal. But to populate that page, you may take existing content from other sections of your portal. To do this, you select a portlet from your admin menu and tell your portal page to use it. You typically select a bunch of these to build up a page's content.
In Drupal we can do similar things to populate content, but this type of modular approach to individual page building is usually left to content management systems like Mambo/Joomla and the commercial portal CMS's. To stack blocks of content in Drupal, we need to do a little more work and take a few more steps, but it's doable. One approach is to build your content modules within Drupal's block system. And then when you create a new page (has to be a PHP page), you simply insert block calls into your page body.
Here's an example showing how a typical portal page is built and how you might build a Drupal page with blocks in a similar manner:

So you see that what I plan to do is display a block using PHP. To give you an example, let's take a to do list. I'm a fan of the GTD method of time management, so I created a new "To do items" content type using flexinode. Taking that example in the diagram above, I want to insert a block of my latest to do items in a content area on the left, and a list of new links I've tracked in a content area on the right.
Inserting blocks in Drupal pages
To insert the blocks, we use some PHP code in the page body and be sure to select "PHP code" for the Input format. (More on this technique in the Drupal node: Placing the contents of a block in any location.)
PHP code to insert my to do list
For this content area, I created a block that does an SQL search for my to flexinode-5 items. Then I use the module_invoke() function to display the block within the page. Note that "7" is the ID number of the block I created in the admin -> blocks menu.
<?php
$block = module_invoke('block', 'block', 'view', 7);
print $block['content'];
?>
Alternatively I can simply insert the PHP with the SQL statement into the page itself like so:
<?php
$sql = "SELECT node.title, node.nid FROM node WHERE type='flexinode-5' ORDER BY node.created DESC LIMIT 50" ;
$output .= "<ul>";
$result = db_query($sql);
while ($anode = db_fetch_object($result)) {
$output .= "<li>".l($anode->title, "node/$anode->nid")."</li>";
}
$output .= "</ul>";
$output .='<div class="more-link"><a href="to_do_list" class="small">more</a></div>';
print $output;
?>
Displays this:
PHP code to insert latest blog entries
<?php
$block = module_invoke('blog', 'block', 'view', '0');
print $block['content'];
?>
Displays this:
Wrapping it up
That's it really. You can then use CSS to format your columnar layout. Very simple method to get near portal-like functionality. Might be nice if the "Page" content type used the content management model so we select blocks of content from within the "Create" interface and move the blocks around. That would require an entirely new administration UI, however.If you get comfortable with the method above, this might be a suitable approach for re-using content in pages. This is one method I would definitely try using in client's sites, but your site administrator will have to be familiar with PHP to create these kinds of blocks. Anyone who's wanting this kind of functionality and who is not comfortable touching PHP might be better served by other CMS packages.
Just noticed this new wiki feature today. Broken in Safari at the moment. They must have been adding this as I was trying it, because when I added the link to the wiki on Lou and Peter's book page, the URL wasn't clickable initially. When I revisited the page a short while later, the link was clickable. Strange. Wonder how this will be abused.
I noticed the citations feature today as well. Don't know how long it's been there. These are the citations for Lou and Peter's IA for the WWW book
Talk about feature creep. Amazing how much stuff they're cramming into these pages. Peter pointed out to me that they removed the sidebars, a detail I actually didn't notice before he mentioned it.
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.

