Graycor: Drupal Theming in the Works

Back in June I wrote about how to theme correctly in Drupal (Sustainable Markup: How to be a themer in Drupal). At that time I was working on a new website for Graycor, a leading provider of construction, maintenance and facilities services throughout the U.S., Canada and Mexico. So much of what I wrote about in my last blog entry relates specifically to the newly launched (August 25, 2008) Graycor site.
We set 3 goals for ourselves before we started the prototype build out:
- Avoid using tpl.php files where ever possible.
- Create default CSS styling and reuse as much as possible, "Theme" don't "Skin"
- Leverage the Drupal admin everywhere we could.
And we did just that. We succeeded in reaching our 3 goals on this site.
Let me break down for you what we did...
Avoid using tpl.php files where ever possible.
To avoid using a tpl file for every content type or layout, we planned strategically before building out the Drupal site. Actually let me step back a bit and explain what "strategically" means. Before we build out a Drupal site at Palantir, we generate a Design Implementation document (which in this case was a set of designs scribbled on, in most other cases a PDF with comments) and then there's the Data Model. The Data Model is the key to a successful site and its what makes theming sustainable.
The Data Model is generated in excel, with many worksheets inside of it listing all elements of the site, thus becoming a set of instructions for someone to build out the Drupal site. It lists every field, its options, its Drupal display settings, and its CSS display settings among other things. This document has to be so detailed that we can give it to anyone in the office (who knows Drupal) to build. It even includes help instructions, because seriously who wants to be adding those in right before site launch.
By walking through the Data Model, field by field, you start to architect a site that can reuse CCK fields on multiple content types. We also standardize our field naming convention at this point. Now remember...we haven't even installed Drupal, this is all Excel. The other benefit of reusing CCK fields is to increase the speed at which you can create Views. When you have 5 different Views that all have teaser copy and thumbnails, you WANT to clone as much as you can.
When we're architecting out the site in the Data Model document we're also thinking about how we're going to build it out with CSS, and how specifically we can avoid destroying the $content variable in the node.tpl.php file. For Graycor we only needed 1 node.tpl.php file - for individual projects because of the required formatting for taxonomy. We thought long and hard about how we could use the display settings through CCK and how we could position items with the code we knew Drupal would spit back out at us. This process took approximately 20 hours. Which leads me into our next goal...
Create default CSS stylings and reuse as much as possible, "Theme" don't "Skin"
The first step to theming (in my book anyway) is to understand your fields, how Drupal's gunna spit them out and how you're gunna grab onto them and reuse them. Ok thats more like 4 steps, but still it is one process. So how do you do this? Its actually easy, just tedious. If you're gunna create a date field...you name it something predictable, like "date". This means that Drupal labels it "field_date", and your div class around that date field will be something like "field-field-date". If you need to add another date field with different field requirements, you name it "date_news" or something related to the content type. Or how about an even better example...lead copy. Lead copy is a field that we always use as the "teaser" or the shortened and editorially controlled copy that is displayed on a View in place of the body. We know that on our site 5 different content types will be rolled up into a view and will have a thumbnail. We also know that all 5 content types have lead copy. That means if we use the same field for each (if the requirements are the same of course), then we get a class of "view-data-field-lead-value" on our wrapping div for that item in the View. Thus letting us style defaults for a View that uses List style, shows a thumbnail, title and teaser copy. Here's an example: http://graycor.com/projects/results/49.
Of course at a certain point you are going to have to get more specific with your CSS, but our goal was to avoid the amount of times we needed to restyle new content in the site. We wanted the site to be flexible enough that if the client wanted to add a brand new view of any style type (table, full node, etc.) it would be styled already for them.
Leverage the Drupal admin everywhere we could.
Leveraging the Drupal admin? What does that mean? Well it means make as many things configurable from the admin as you can. This means if you can avoid using the views theme wizard (yes this is a Drupal 5 site), then you can rearrange your fields on the view all you want, never having to open a tpl file. We also try to use CCK labels where ever possible. For instance on the project pages, we use the CCK label of "Project Scope" and the "Client" label as well. Our rule of thumb is that if you can use a CCK label you should, because if you don't, guess what you might need a node.tpl.php file, and like I said earlier,...we're trying to avoid those. You don't want the client to need FTP to edit their site. Drupal is a CMS, use its admin, and let the client use it too.
The other option of course is to use preprocess functions, which Larry Garfield so graciously back ported to D5 for us: http://www.garfieldtech.com/blog/preprocess-drupal-5. I'll let Larry explain this one in detail because I don't think I could do it justice. But for those who are less of a programmer, like myself, it basically helps you do thinks before the page is processed, like wrap a link cck field around an image field :). Quite handy, and helps with that no tpl.php thing.
The last and final piece to pull all 3 goals together is to build an Interactive Prototype. For Palantir this means build your entire site map out - based on the Data Model, build the content types, the greeked content, the views, everything. And use the Zen theme. Then you can start CSS, but not until this point. You can't build CSS defaults without the entire site built out in Drupal.
So why was Graycor so successful from a theming perspective? Because we were testing functionality during a Prototype stage that we often wait until Beta to do. Beta became more about content review and final tweaks and less about custom functionality and Views setup. This was our goal, and we achieved it. And Graycor is a rock solid site ;)
Oh yeah and did I mention we live, eat, breathe, and die by Zen, use it, be it. Zen.
2211 North Elston Avenue
Suite #202
Chicago, IL 60614
773.645.4100 p
773.645.4105 f




Thanks!
listening to your workflow as a themer is great! thanks for taking the time and energy to write this up. I am really interested in the way you use the Data Model. Do you construct this with the client? or do you make it based on what they give you? do you template.php to modify/add variables to avoid creating more tpl files?
thanks again- looking forward to reading more.
Hi Jared, Thanks for
Hi Jared,
Thanks for commenting. We generally do not show the Data Model to the client, unless they are technically savvy and want to see it. Most often its filled with internal jargon that only makes sense to us Palantiri. We do however make a more client friendly document that we call the "Design Implementation" doc. This generally consists of a pdf of the designs and/or wireframes (sometimes we do get designs before functionality which makes this data model process even more important). We then use Acrobat Pro to "comment" on parts of the site. We try to use words like "page" and "content" and "page refresh" instead of CMS/web terminology like "node" or "page load". We use this document to confirm our understanding of the intended functionality with the client.
We do also try to teach our clients about Drupal. Our mission is not to obscure Drupal, rather to make Drupal more approachable. We do this by teaching them what nodes are, and why we use modules, and why its so great to be working with a community like Drupals'. Although I recommend not teaching your client about Drupal until after the site is done. You don't want to spin incredibly technical webs around your client in the initial stages.
You are also correct about the way we use template.php. We put our preprocess functions in there (although actually recently JohnAlbin, maintainer of Zen and other assorted items and who works with us here, showed me a preprocess function that could be added to the custom module, thus making it more portable to all node types).
thanks
thanks for the reply...
I saw the slides from Szeged, good stuff. I am enjoying this peak at your workflow. Please keep writing, your insights are appreciated. The real work examples are also really helpful... if you are taking requests I would love to hear your approach to theming the views on the Graycor site. Do you use tpl files for the list views? thanks a bunch
Because this is a D5 site,
Because this is a D5 site, yes we did use a number of views templates. In fact we have 34 views on this site. Although 15 of those are only meant for the site maintainers. We like to "beef up" the admin and customize their site management/content creation process.
So for the remaining views that are used on the theme side, we used the Views theming wizard. One thing that we do try to do where possible is reuse templates. For example: The list of offices view. List of nodes, grouped by State. http://graycor.com/contact/offices. Now look at this page: http://graycor.com/blasting/locations. Different view, same views tpl.php file. That way if the client decides to redesign any part of the layout, only 1 template needs to be modified, and both share consistent markup.
One thing that took me a while to realize is that I didn't need to remove anything from the tpl file generated by Views Theming Wizard. For instance, I try very hard to leave the variables that control the labels for each field. That way the client can modify the label from the Views UI. But then again I should be clear about that workflow as well. We often turn off the Views UI (for performance reasons and preservation of code) and always port Views to code. Most of our clients don't ever need to touch Views, especially if we set it up correctly in the first place.
Another trick that we've come across in D5 is the process of disabling the default $body field and creating a CCK "Body" field in its place. We do this so that we get a unique class around the content added to the body - just in case we need to float it right or position somewhere specific. When you use the default $body field, you don't get a div around the field, making it sometimes difficult to theme. Another benefit of a CCK body field is that you can then also use that easier in a View. In Views 1 adding a body field to the View essentially prints out $content. This is not useful to us. We want to "re-jigger" those fields a bit. Of course, as I said before...I'm still getting my head wrapped around Views 2 and D6 - and I hear that I'll get more flexibility when I make that transition.
Really interesting writeup -
Really interesting writeup - thanks !
I'm not sure why you want to avoid templates at all cost - this is sort of contrary to the D6 trend which is to make using templates easier.
Also, this patch for CCK (D6) might be of interest : http://drupal.org/node/300368 - feedback welcome on the idea.
I'm actually a bit
I'm actually a bit embarrassed to say that I have yet to theme in D6! (But I'm also going to call out JohnAlbin on that too). Its the nature of our world I think. We can't build a site for a client if all the modules aren't out there yet, and of course then the schedules don't align. I am however in the process of developing a site in D6 that is pre-theme. It is essentially in "Interactive Prototype" stage. Meaning that the site is built out in Drupal, views and all, and it just needs the drapery. So I have no doubt that I'll be writing about a newly expanded approach to theming for D6 very soon.
As for the avoiding of template files, well...we do that b/c we want to have reusable theme elements. If I create a node-[name].tpl.php file, and I break out $content, I now have abandoned ship. I no longer have those wonderfully long classes for each field, thus requiring me to build HTML out again. We don't want to waste time writing HTML. Drupal does it already, we mind as well use it. Let Drupal do the heavy lifting for us.
Now the thing that Views 2 does, that is fantastic, is the optional use a "default" tpl files. You can style 1 specific field for all views, or for all list style views, etc. That's the great part. If I need spans instead of divs for a specific CCK field I can do that for every single view that field appears on. So I'm not opposed to tpl files, we're just trying to avoid relying on them too much.
And any customization to fields, we prefer to add those to template.php or the custom module.
It's all about maintainability and portability
As someone who has had the opportunity to do some limited theming in Drupal 6, two of the most welcome new features for me so far are the additional configuration options available in the theme’s .info file (which reduces the need to touch template.php) and the enhanced support for subthemes.
One of the points that I made in my Drupalcon presentation is that themers should do as much as possible using CSS and avoid touching template.php or the .tpl.php files unless it’s absolutely necessary. The advantage of this approach is that it makes the theme more portable, more upgradable, and ultimately more maintainable. If one of our clients wants to modify the look and feel of their site after it’s launched, it’s much easier (and safer) for them to modify CSS files in a subtheme directory than to either hack a fully custom theme or try to rewrite it from scratch.
Zen provides a really great framework for theme development that already solves a lot of the basic problems that come up for any Web site, such as browser resets, font size and spacing, etc. It also uses a very flexible and standards-driven approach for creating fully CSS-based layouts using semantically driven XHTML markup. By moving as much of the presentational layout into CSS as possible, we not only build a site that is more flexible and maintainable, but will also work better across more browsers, and provide support for things like mobile devices or browser readers for the visually impaired.
The heading is out-of-context
Actually, maybe that heading should read “Avoid modifying tpl.php files where ever possible” or “Avoid using template suggestions files where ever possible” instead of “Avoid using tpl.php files where ever possible”.
What we are really trying to avoid is sticking tons of PHP into a tpl.php. And you should NEVER be removing any variables that are available in the default template. This is especially true of the $content variable in the node.tpl.php.
As theme designers, we often want to break up the $content into its pieces and place them where ever we want in the tpl file. But modules can alter the $content variable, and by removing that variable from the template, we have “broken” the module.
Also, if you are theming all of your content by creating a node-NODETYPE.tpl.php for every type of content of your site, any new content type is going to look funky until you re-style it.
As for “having never developed a theme in Drupal 6”, I plead the 5th. Doesn’t Zen 6.x count? :-p
John, thanks for clarifying
John, thanks for clarifying that. You are absolutely correct about the modification of the .tpl.php files being the real issue. You definitely explained this better than I could.
But modules can alter the
But modules can alter the $content variable, and by removing that variable from the template, we have “broken” the module.
True - that's why I pointed to http://drupal.org/node/300368 which attempts to provide some flexibility around $content and CCK fields. Not a generic solution, but CCK can only affect CCK fields...
By the way...check out George
By the way...check out George DeMet's presentation at Drupalcon Szeged: http://szeged2008.drupalcon.org/program/sessions/dos-and-donts-designing...
George walks through the workflow process.
Great post Colleen! I think
Great post Colleen!
I think you guys have the right idea first focusing on how Drupal outputs and themes data... vs. the other way around.
- how do you suppress fields or include CCK fields from the $content variable without changing the output in the tlp?
Thanks
Guy - We usually try to
Guy -
We usually try to control whether or not we see a cck field on the node's display by setting its display filter to "" for both teaser and full. We generally don't use the "teaser" display so we always just set that to the same as full.
When we can't turn it off via a display filter on the field, then we may use CSS to display: none. But of course this won't work for everything and we only do this when the data is actually good to have around for semantic markup reasons. This method is less likely used.
The third option is to weigh the differences between just creating a tpl file or writing a preprocess function to remove it from the $content variable.
yched posted a patch for CCK that I believe allows you to suppress the field and "reprint" it outside of $content. Its for D6 and I haven't used it yet, but it look promising. Here's a comment from JohnAlbin (who works here at Palantir) on yched's patch: http://drupal.org/node/300368#comment-1008197
John also states how we got around this in D5.
Wow - great stuff. I
Wow - great stuff. I appreciate the insight!!!
I wonder if we can pull together a Drupal Theming event in Chicago sometime and promote it via drupal.org. Best practices, case studies, etc. I am originally from there and know at least a few others interested in attending. Any interest?
whoops - jumped the gun.
whoops - jumped the gun. Just found the Chicago Drupal camp next month. Could be good!! http://cdmug.org/node/198