DesignKarma Redesign: Chapter 3
2 comments. Filed under “ExpressionEngine”, “General”
The previous two chapters of this series focused on the spec, design and setup of the new DesignKarma website. In this final chapter we’ll give an overview of how the site was built in ExpressionEngine—looking at our variables, snippets and templates.
The new site isn’t typical of our EE builds because it’s a little more hard-coded than content managed, and a little simpler overall than regular projects. However, it’s a chance to give a glimpse of how we power our sites using EE and invite feedback on how other folks do it!
Getting started
EE developers regularly talk about “chunking up” their pages into blocks of code. In some cases this may involve building a full static page or pages, before deciding on the best way to chunk certain elements. More often than not though, this chunking process happens fairly quickly in the developers head, before diving straight into markup.
That was certainly the case on a simple site like ours, where it’s obvious from the design which elements should be chunked as reusable code blocks, and which are page-specific. From there it was a case of creating our global variables, snippets and templates in EE and firing up our favourite HTML editor (TextMate).
Global variables
EE’s Global Variables are perfect for holding simple data like phone numbers and other information that will be repeated throughout a website. They parse ahead of everything else in EE, so they’re kind of limited— no EE tags or PHP allowed. They’re not particularly client-friendly either (we prefer Low Variables for that), so we tend not to use them all that much.
We recently took over a website built by another agency and it had about 50 global variables for things like {container_div_start_tag}. Abstracting your code to this degree has some advantages, but it’s way overboard in our opinion, making updates a real headache. We like simple.
There are only four global variables on our site, and I’m not going to spend a great deal of time detailing them because they don’t really do much! Briefly, they are:
{doctype}contains our doctype declaration, in case we decide to change it{address}contains our street address, used in various places on the site{author}populates our meta author tags{modernizr}contains a link to the latest Modernizr script
Modernizr is a script that helps us take advantage of the latest web technologies used on our new site, whilst accommodating older browsers that haven’t caught up yet.
A note on naming conventions
On larger sites we like to prefix our global variables with “gv_”. We prefix other elements too, like path variables (pv_) and snippets (sn_), so it’s obvious what each element is in our code— useful not only during development, but also five years down the line when you come back to make changes. The DesignKarma website is pretty simple though, so we didn’t bother prefixing.
Snippets
New to EE2, snippets are a great way to reuse blocks of code. Like global variables, you can go a little overboard with these, but when used correctly they’re an important way of managing your code and improving performance. Unlike global variables, you can include EE tags and PHP to really make snippets super useful.
We have a number of repeated items on the site that we decided to turn into snippets.
{body_conditions}
We’ve been building some sites lately using HTML5 technologies, and we use a home brew of code distilled from Paul Irish’s popular HTML5 Boilerplate. Part of that codebase includes some HTML conditional comments to write classes on the <body> tag for Internet Explorer, so we can provide some CSS workarounds for common IE rendering issues. It’s a pity we still have to target workarounds for specific browsers in this day and age (I’m looking at you Microsoft), but having all this crap in a snippet means that one day hopefully we can just strip out the comments and go back to a simple <body> tag instantly across the entire site.
Aside from that, the other purpose of this snippet is so we can add a section class to our pages. Here’s how it all works:
{if segment_1 != ""}
<!--[if lt IE 7 ]> <body class="ie6 {segment_1}"> <![endif]-->
<!--[if IE 7 ]> <body class="ie7 {segment_1}"> <![endif]-->
<!--[if IE 8 ]> <body class="ie8 {segment_1}"> <![endif]-->
<!--[if IE 9 ]> <body class="ie9 {segment_1}"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--><body class="{segment_1}"><!--<![endif]-->
{if:else}
<!--[if lt IE 7 ]> <body class="ie6"> <![endif]-->
<!--[if IE 7 ]> <body class="ie7"> <![endif]-->
<!--[if IE 8 ]> <body class="ie8"> <![endif]-->
<!--[if IE 9 ]> <body class="ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--><body><!--<![endif]-->
{/if}
So what’s going on here? We’ve got a mix of EE and HTML conditions that add classes to our <body> tag. Let’s start with the EE conditions. Firstly, we check to see if segment_1 is available, which means we’re in a section; not the homepage.
designkarma.co.uk/index.php/here_is_our_section_segment
If we’re in a section (e.g. About) we want to add that segment as a class to our body tag (e.g. body class=”about”) so we can add some section-specific CSS like repositioning the background image. If no segment is available then we’re on the homepage so no need for a section class.
The HTML comments inside our EE tags are borrowed from HTML5 Boilerplate, and add <body> classes for Internet Explorer browsers, so we can target any CSS workarounds.
{footer}
No prizes for guessing what this is. The footer is exactly the same on every page, so it makes an obvious snippet. There’s nothing of great interest in this snippet of mostly static HTML and a few EE tags, so let’s move on.
{masthead}
The masthead snippet includes our main menu. The {segment_1}}conditional comes in handy again, this time to add an “active” class so we can style the currently active menu item.
<header>
<a href="#msg" class="visuallyhidden">Skip navigation</a>
<nav>
<ul class="clearfix">
<li><a href="{homepage}" class="ir dk" title="Web Design Manchester">Web Design Manchester, {site_name}</a></li>
<li><a href="{path='about'}"{if segment_1=="about"} class="active"{/if}>About</a></li>
<li><a href="{path='what'}"{if segment_1=="what"} class="active"{/if}>What We Do</a></li>
<li><a href="{path='folio'}"{if segment_1=="folio"} class="active"{/if}>Portfolio</a></li>
<li><a href="{path='blog'}"{if segment_1=="blog"} class="active"{/if}>Blog</a></li>
<li><a href="{path='contact'}"{if segment_1=="contact"} class="active"{/if}>Contact</a></li>
</ul>
</nav>
</header>
{scripts}
Generally speaking we like to keep all our scripts in one snippet, with conditions to load scripts and call functions depending on page (or {segment}). This snippet is always added before our template’s closing <body> tag, and in this instance includes:
- A link to the latest jQuery repository, hosted on Google
- Links to the the various jQuery plugins used on the website (Tooltip, Nivo Slider, and Validate), plus associated functions
- Our Google Analytics
{teasers}
Our final block of reusable code is for the teasers that appear on the Homepage and Portfolio pages. They give short intros to the “About”, “What We Do” and “Blog” sections. Most of this is hard-coded; only the blog entry is dynamic.
{exp:channel:entries
cache="yes"
channel="blog"
disable="categories|member_data|pagination"
dynamic="no"
limit="1"
orderby="date"
refresh="30"
sort="desc"
sticky="yes"
}
{if no_results}<p>Sorry, the blog is currently closed!</p>{/if}
<h2><a href="{title_permalink='blog/comments'}" title="Read “{title}”">{exp:trunchtml chars="28" exact="yes" inline="…"}{title}{/exp:trunchtml}</a></h2>
<p>{exp:trunchtml chars="115" exact="no" inline="_[…]"}{exp:tagstripper:stripAllTags}{summary}{/exp:tagstripper:stripAllTags}{/exp:trunchtml}</p>
<p><a href="{title_permalink='blog/comments'}" title="Read “{title}”">Continue reading</a></p>
{/exp:channel:entries}
We always like to use the cache/refresh and disable parameters in our channel entries tags to make sure our engine is running as efficiently as possible. You’ll also notice some 3rd-party plugin code ({exp:trunchtml} and {exp:tagstripper}). This is outlined in Chapter 2, but they basically exist to chop any long blog headings or summaries, so our Blog teaser lines up nicely with the other two teasers.
Bringing it all together with templates
With our code successfully chunked up into variables and snippets, it was time to start on our template groups and templates.

There’s no point going into detail on every single template here. Instead, we’ll illustrate how the bulk of our templates work, as well as picking out a couple items of interest.
Barebones
Pretty much every template on the site has the same basic outline:
{doctype}
<html lang="en" class="no-js">
<head>
<meta charset="{charset}">
<title>Web Design Manchester, Web Development, ExpressionEngine | {site_name}</title>
<meta name="description" content="DesignKarma designs and develops ExpressionEngine websites, bringing over a decade of experience to your web project">
<meta name="author" content="{author}">
<link rel="alternate" type="application/atom+xml" href="{path='blog/atom'}">
<link rel="alternate" type="application/rss+xml" href="{path='blog/rss'}">
<link rel="stylesheet" href="{stylesheet='_css/index'}">
{modernizr}
</head>
{body_conditions}
<div id="container">
{masthead}
…main content goes here…
{footer}
</div><!--/container-->
{scripts}
</body>
</html>
Our global variable ({doctype}) is first up, with a couple of EE’s standard global variables next ({charset} and {site_name}). The {author} global variable rounds out our metas, before we link to our Atom and RSS feed templates.
To minimise HTTP requests, we like to link to one stylesheet (_css/index) and use media queries in the stylesheet itself for print and (coming soon) smart phone styles.
All that’s left now is to add our {modernizr}, {body_conditions}, {masthead}, {footer} and {scripts}.
Taking it a step further
Where our basic outline gets slightly different is on single entry templates— for example a single project page or blog article. On these templates we want to throw some data into the <title> and <meta> tags, so we need our EE tags at the start.
{exp:channel:entries
channel="blog"
disable="category_fields|member_data|pagination"
dynamic="yes"
limit="1"
require_entry="yes"
}
{if no_results}{redirect='error'}{/if}
{doctype}
<html lang="en" class="no-js">
<head>
<meta charset="{charset}">
<title>{if browser_title}{browser_title}{if:else}{title}{/if} | {site_name}</title>
<meta name="description" content="{meta_description}">
The example above shows our “comments” template—used to display the page you’re looking at right now. As usual we’re optimizing the engine by disabling stuff we don’t need with the disable= parameter. We’re also using the require_entry parameter to improve error handling on mistyped URLs. Without this, someone could type anything in segment_3 and EE would show our latest entry by default. Well, I don’t really want our latest article being linked to or indexed as:
designkarma.co.uk/index.php/blog/comments/the_most_boring_article_ever
So using the require_entry parameter is a nice save for mistyped (or mischievous) URLs.
Also in the above code, we’re using our custom fields aimed at improving SEO ({browser_title} and {meta_description}). Note, we’re checking to see if our {browser_title} field contains a value or not. If it doesn’t, we fall back to the entry {title}.
Marking up the blog with HTML5
Okay we may be going a little off-piste here but I thought it might be interesting to outline how we mark up our blog using HTML5 and EE.
HTML5 is a fairly new technology and there is still some discussion on how best to markup a blog, so we thought we’d chip in. Also, we haven’t seen any examples of HTML5 blog markup with EE tags yet so let’s add that in to the mix while we’re at it.
{exp:channel:entries
channel="blog"
disable="category_fields|member_data"
dynamic="yes"
limit="5"
}
{if no_results}<p>Well that's embarrassing! There are currently no blog entries available. Please check back soon.</p>{/if}
<section>
<header>
<hgroup class="clearfix">
<h1><a href="{title_permalink='blog/comments'}" title="Read “{title}”">{title}</a></h1>
<h2><time pubdate datetime="{gmt_entry_date format='{DATE_W3C}'}">{gmt_entry_date format="%d %M %y"}</time></h2>
</hgroup>
</header>
<div class="details">
<p class="author">Posted by {author}</p>
<p>{if allow_comments}<a href="{title_permalink='blog/comments'}" title="Read “{title}”">{if comment_total==1}1 comment{if:else}{comment_total} comments{/if}</a>. {/if}Filed under {categories backspace="2" disable="category_fields" style="linear"}“<a href="{path='blog'}" title="View all entries in this category">{category_name}</a>”, {/categories}</p>
</div>
<div class="summary">
{summary}
</div>
</section>
{paginate}
{if {total_pages} > 1}
<p class="pagination">
{if previous_page}<a href="{auto_path}" class="prv">Previous</a> / {/if}
{if next_page}<a href="{auto_path}" class="nxt">Next</a>{/if}
</p>
{/if}
{/paginate}
{/exp:channel:entries}
The code block above outputs our last five blog entries in date order. HTML5 newbies will spot the new <header> and <time> tags right away. Note that we’re using EE’s handy {DATE_W3C} formatting variable to format the entry’s datetime attribute just how the W3C likes it.
One other point of interest is oftentimes we only want to show pagination links when needed rather than by default. To do this (and there are various other ways) we surround our pagination links with the condition:
{if {total_pages} > 1} …show our pagination links… {/if}
In other words, if the number of entries exceeds our limit (set as five in this case) and requires another page; show the links.
A bit of CSS trickery
One last thing it might be fun to share with you is how we built the three random screens feature on the homepage.

Grabbing three random entries from the folio is the easy bit:
{exp:channel:entries
channel="folio"
disable="categories|member_data|pagination"
dynamic="no"
limit="3"
orderby="random"
search:folio_show="=Yes"
sticky="yes"
}
Here, we’re being careful to only select entries with the custom field {folio_show} set to “Yes”. We created this field because we want to restrict which projects we display on the homepage.
Next, we need to output screens for the three projects in seperate <div>s with their own ids, so we can position and overlap them with CSS. To further complicate things, we need the first screen to be larger than the other two. So here goes:
<div id="screen_{count}">
<a href="{path='folio'}" title="Check out the portfolio">
{if count == "1"}
{exp:ed_imageresizer
alt="{title}"
debug="yes"
forceWidth="yes"
image="{folio_img_1}"
maxHeight="319"
maxWidth="460"
}
{if:else}
{exp:ed_imageresizer
alt="{title}"
debug="yes"
forceWidth="yes"
image="{folio_img_1}"
maxHeight="229"
maxWidth="330"
}
{/if}
</a>
</div>
Here, we’re creating three <div>s with their own ids depending on result {count}— i.e. #screen_1, #screen_2, #screen_3. For the first screen (where {count} is 1) we use the ED Image Resizer plugin to resize and cache the screen image at the larger size of 460 x 319 pixels. Subsequent screens are re-sized and outputted at 330 x 229 pixels. Now we need to positioning and stack these layers with CSS to give us our three dimensions:
#screen_1, #screen_2, #screen_3{
float: left;
position:relative;
}
#screen_1{
margin: -286px 0 0 219px;
width: 462px;
z-index: 98;
}
#screen_2{
margin: -271px 0 0 0;
width: 332px;
z-index: 97;
}
#screen_3{
margin: -271px 0 0 608px;
width: 332px;
z-index: 96;
}
On top of the three screens we’re floating the transparent PNG shown below.

This gives our browser chrome outlines and a nice bit of light and shade on top of our screens. We could’ve included the outlines and shading on the actual project screen images, but we preferred to keep these pure in case we wanted to apply a different treatment or decoration at a later date, if that makes sense.
So, before our <div id=”screen_1”> we have an empty <div id=”chrome”>. Not very semantic I’m afraid, but allow us some creative license here. To get this layer to sit on top of everything the CSS goes like this:
#chrome{
background: transparent url(/images/cover.png) 50% 0 no-repeat;
float: left;
height: 301px;
position:relative;
width: 940px;
z-index: 99;
}
To finish off, we added some borders to our screens…
#screen_1 img, #screen_2 img, #screen_3 img{
border-bottom: 1px solid #999;
border-left: 1px solid #999;
border-right: 1px solid #999;
}
...and we’re done.
It’s a wrap
That about does it for this series. Maybe you’ve learnt something, maybe you haven’t. But I always find it fascinating to see how other EE developers work and thought it was about time DesignKarma contributed something. Hopefully we’ll continue to post more EE insight, tips and tricks when we can.
We’d love to hear your feedback on the above, and how you build your EE sites. Why not leave a comment below?
What do you think?
Leave a comment
Nice easy to follow example as always
A little bit off subject but I’ve recently discovered Textmate (I created this blog post in it!) and find it a joy to use. Prior to this I was a Dreamweaver user and while Dreamweaver has some nice tools it is rather bloated! A couple of weeks invested in trying this tool out will pay dividends! The adds on (called Bundles) are useful and one of my favourites is Zencoding.
here is a great screencast I found about the power of Textmate, its packed with good stuff!
If you are looking to make the transition, then Dreamweaver can always be left ticking over in the background and used when necessary? I’m currently investigating coda and Espresso too.
Back to Expression Engine, I like the idea of keeping things simple where possible. Using a sparse number of global variables seems sensible, rather like an artist having a limited palette of colours to create a more unified composition.
How sad that we web developers are caught up in this state of competition with browser manufacturers showing little regard to standards and browser wars constantly breaking out! The big culprits are Microsoft although Mozilla and Webkit are not immune to the practice with their own proprietary implementations of CSS3 properties. The body conditions snippet proposed by Ian is a pretty elegant solution to the problem of targeting ie browsers.
It was only recently that I discovered the method of adding a class to a body tag to control different page layouts. I found this article on body classes to control page layouts pretty useful.
I can see me lokking at this article again as I begin to use ee, thanks a million
The body conditions snippet proposed by Ian is a pretty elegant solution to the problem of targeting ie browsers.
Leave a comment
Only these HTML elements are allowed in comments.