Services Newcastle’s most advanced web company. Learn more ›

Photo of Wayde Christie

Wayde ChristiePixel Wrangler

Newism Pty Ltd
Newcastle, NSW Australia

Building Campaign Monitor Part 2 - ExpressionEngine Template Groups

This second article in the series should be all the template group therapy you need.

Templates are the presentation layer for ExpressionEngine sites. All of the front-end code, including XHTML and ExpressionEngine tags go in a template, and all of those templates, go in a template group (which is a kind of virtual folder). Template groups are the focus of this post, and we’ll cover individual templates in the next one (that’s if I’ve not been executed for pun-crimes against humanity in the meantime).

A bit about URLs

Templates and template groups are integral to ExpressionEngine, because they determine how ExpressionEngine constructs its URLs and ultimately renders its pages.

In a default install, ExpressionEngine constructs its URLs like so:

http://www.yoursite.com/index.php/template-group/template-name/

Most of the URLs in the Campaign Monitor site work this way, but with a couple of minor differences.

Firstly, we remove the index.php bit with some Apache magic, skillfully performed by LG .htaccess Generator. There’s no requirement to do this however, and the only reason it’s done in most cases is to tidy up the URL.

Removing ‘index.php’ turns our URL into this:

http://www.yoursite.com/template-group/template-name/

Doing so for us is purely an aesthetic thing, but in Campaign Monitor’s case it was vital. The old Campaign Monitor site didn’t have index.php in any of it’s URLs, which meant we needed to match the URLs from the new site exactly so that search engines didn’t get confused and users didn’t end up with a bunch of broken bookmarks.

Secondly, not all of the URLs in the site conform to the /template_group/template_name/ structure due to the Pages Module. Occasionally Freshview (creators of Campaign Monitor) like to shorten their URLs so they’re a bit more user-friendly, and in these cases they use the Pages Module to define a custom Page URI. Custom URIs are exactly that, which means the /template_group/template_name/ structure is completely bypassed and obfuscated, as demonstrated here.

Template Groups

If you’re following on from the previous post in this series, you’ll probably notice that the list of template groups closely matches the list of weblogs. This is a fairly common occurrence, due mainly to the fact that discrete weblogs often require discrete templates.

It should be noted that every template group has an index template by default, but these templates are not used in all cases. When they are used, we’ll provide a short overview of how we used them.

Big list of template groups

Big list of template groups

Global Groups

You’ll notice that the first three groups in the list above all start with an underscore. We do this for two reasons: the list is alphabetical so groups with an underscore appear at the top of the list, and they also indicate our global groups. Essentially, if a template is used in many places in a site, it goes in one of these global groups. The site header and footer includes (which live in the _includes group) are good examples. This approach isn’t a requirement, but it works well for us so we’ve stuck with it.

The majority of the templates in these global groups are named .template-name. The period at the beginning of the file name stops the template from being browsed directly, as it effectively makes the template invisible on the server (much like .htaccess files).

Template Group: _components

This group is for templates which may be used in several places throughout a site, but are not necessarily global. The main template that goes in there (and the only template in Campaign Monitor’s case) is the ExpressionEngine comments loop.

_components Templates

_components

Templates
  • .comments – The comments loop can often be utilised in several different locations throughout a site, so we put it in an include, pass in a few parameters and place it where necessary (more on this in the next post).

Template Group: _includes

The _includes group contains global templates. Headers, footers, navigation etc.

_includes Templates

_includes

Templates
  • .foot – The footer in the Campaign Monitor site changes quite a bit from section to section. There are unique footers for the home page, blog index, support pages and sales focused pages, and each of these footers are relatively feature rich. So each individual section footer is placed in an include, and embedded in the main .foot template, then a few conditionials determine what include is used and when.
  • .foot-blog – Pulls recent posts from the blog, and also lists blog and gallery categories.
  • .foot-home – Pulls recent content from the blog and the forum.
  • .foot-support – Displays related help content like so.
  • .foot-promos – Several sections in the site display a horizontal row of graphical promos in the footer. These promos are usually displayed randomly, but in some instances the order can be overridden.
  • .head – Contains the main navigation, as well as logic for the home page and masthead graphic titles.
  • .nav_01 – The lovely sub-menu in the left column.

Template Group: _forms

The majority of the forms in a site, particularly blog-centric ones, can often stand to be used in several locations. The Campaign monitor site has comment forms in both the blog and gallery sections, and also has several bespoke forms for the contact and sign-up pages. In general we seperate all of our forms out as includes, mainly because form related pages often have a decent amount of logic associated with them and tend to get quite lengthy code-wise. Best to break them up a bit we find.

_forms Templates

_forms

Templates
  • .comment – Standard comment form used for the blog and gallery sections.

Template Group: feeds

The original Campaign Monitor site had several RSS feeds, and the new version is no different. The difference is, all three feeds are now handled by one template with a bit of logic. Much nicer.

_feeds

feeds

Templates
  • index – The standard ExpressionEngine RSS template was used here, and content is output based on URL segment variables. Essentially we use the first segment of the feed URL as the weblog value for the RSS weblog loop. eg. http://www.campaignmonitor.com/blog/ outputs the blog feed, http://www.campaignmonitor.com/gallery/ outputs the gallery feed, and http://www.campaignmonitor.com/blog|gallery/ outputs both the blog and gallery feeds in one.

Template Group: api

The API section of the site has a sub-navigation column on the right of the page, and each page follows the standard ExpressionEngine /template_group/template_name/ structure.

api

api

Templates
  • .sidebar – A simple include with two weblog loops outputting the API Kits and Methods in the right column.
  • index – A basic page template which embeds the .sidebar include.
  • kits – Outputs the Kits index page, including a list of inline anchors to each kit. Originally each kit was to have its own page, but at launch it was decided to keep them all together.
  • method – Outputs API Methods.

Template Group: blog

The blog template group is fairly straight-forward and doesn’t stray too far from a default ExpressionEngine installation. There’s a bit of .htaccess redirection going on in the category pages, but nothing beyond that.

blog

blog

Templates
  • .sidebar – The right column of the blog features a search form, blog and gallery categories, and a fancy Twitter widget.
  • category-archive – Although the blog categories don’t adhere to the standard ExpressionEngine category URL structure, this template is still used to output category pages. Via the magic of .htaccess redirects, this template is called whenever a /blog/category-name/ URL is requested.
  • index – This template embeds the afforementioned sidebar, outputs 5 full blog posts (‘cos Freshview likes it that way), and paginates everything.
  • post – The blog post template embeds the comments loop include (which also contains some pagination code), the comment form include and the sidebar include.

Template Group: casestudies

The casestudies group contains templates that take care of the Case Studies index page, as well as each individual case study.

casestudies

casestudies

Templates
  • .sidebar – Outputs 5 other random case studies.
  • entry – Embeds the .sidebar include and displays an individual case study.
  • index – Displays a featured case study, and 5 random case studies. The featured case study has a custom entry status of ‘Featured’.

Template Group: downloads

The Downloads section of the Campaign Monitor site lists third-party add-ons and extensions, as well as downloadable documents and software bundles.

downloads

downloads

Templates
  • details – Provides an overview of each download and links to the downloadable files.
  • index – Lists all of the available downloads via a simple weblog loop.

Template Group: features

A simple set of templates, with previous/next functionality.

features

features

Templates
  • feature – Each entry is a basic page with custom XHTML.
  • index – A simple weblog loop which outputs entry titles, icons and summaries.

Template Group: pages

The pages template group is used to house static templates with custom content. It also contains the site home page (denoted by the red asterisk).

pages

pages

Templates
  • 404 – When someone attempts to access an invalid URL, they are redirected to this template. This is configured via the ExpressionEngine Global Template Preferences. Freshview handle their 404 pages with typical style, by turning the page into an informative resource rather than a dead-end.
  • index – The site home page. Like all pages in the site, it embeds the .header and .footer includes, but beyond that it’s a static page.
  • pricing – A simple static template, which displays a more sales-focused banner in the footer.
  • sitemap – Not a site-map by normal standards; rather an XML template for Google Sitemaps. There’s a great tutorial on the ExpressionEngine Wiki which explains everything.

Template Group: resources

The Resources section of the site is one of the most content rich. It’s chock-full of brilliant tutorials, faqs, free email templates—you name it! The templates in the group relies heavily on categories, purely because there is so much information to present.

resources

resources

Templates
  • .related_content – Individual entries display a list of links to related content in the right column. The relationships are created with tags and the brilliant Tag Module from Solspace.
  • category-archive – A simple category archive template that displays category headings, images, and descriptions. You’ll notice the /cat/ segment in this URL. This is the ‘trigger’ segment that tells ExpressionEngine which category to display. The category it uses is the segment that comes directly after the trigger.
  • entry – Basic content template which embeds the .related_content include. Entries have a simple bread-crumb menu at the top of each page, and the links in this menu are generated via the Primary Category extension.
  • index – Displays 5 most popular resource entries and a full category list. Popular entries are output via a simple weblog loop with the orderby value set to view_count_one. This tells ExpressionEngine to output entries with the most views.
  • templates – Outputs an unordered list of thumbnails. The fancy ShadowBox pop-ups will be covered in a later post.

Template Group: templates

Occasionally new pages are added to the site which aren’t part of any particular section. These stand-alone templates are for Freshview to use in such cases.

templates

templates

Templates
  • one-col – A single column template for pages like the Campaign Monitor Privacy Policy.
  • two-col-right – A two column template with a narrow column on the right. The Sign Up page is a good example.

Template Group: search

The standard search templates for an ExpressionEngine install.

search

search

Templates
  • index – In a default install, this page would show the Advanced Search functionality. Since the Campaign Monitor site only offers search for the blog, this template isn’t necessary, and since index templates are mandatory, this page will return a 404 if browsed to directly.
  • no-results – Since the search function is only used in the blog, this template embeds the .sidebar include from the blog template group and notifies the user that their search has sadly come to naught.
  • results – This template is essentially the same as the blog index template, except it displays blog summaries rather than full posts.

Template Group: gallery

The Campaign monitor Gallery is basically a slightly tweaked copy of the blog. The templates are near identical, except that the output of the entries is a screenshot and description, rather than a blog post.

gallery

gallery

Templates
  • category-archive – A standard category archive template.
  • entry – Displays a screenshot and description, along with several other custom fields like author name and company.
  • index – Again, this is based on the blog index template.

Template Group: customers

The Customers section is a key marketing area for the site, so there’s lots of bespoke layouts and a smattering of dynamic content.

customers

customers

Templates
  • giving-back – Outputs a list of sponsorship recipients via a weblog loop, and contains a simple form which is handled by the FreeForm extension from Solspace.
  • index – Displays a featured case study for entries with a status of ‘Featured’, and also outputs 3 other random case study entries. Everything else in this template is hard coded.
  • testimonials – A simple weblog loop which outputs customer testimonials. Related case studies are displayed in the right column. These relationships are created using Brandon Kelly’s ‘Playa’ extension.
  • using – A hard coded template that displays several unordered lists of Campaign Monitor client logos.

Template Group: support

There’s lots of content in this section, but due to the fact that it needs to be accessible via the actual Campaign Monitor application, all of it it hosted on a sub-domain. For that reason there are only a small number of ExpressionEngine templates in the group.

support

support

Templates
  • contact – Basic contact form, again using the FreeForm extension.
  • index – A hard coded template with links to all of the Help & Faqs categories.

Phew!

That was quite a post, and if you’ve made it this far without your brain leaking out of your ears you seriously deserve a medal. The remaining posts in this series will hopefully be a little more succinct and infinitely more entertaining. The next post in fact, will be all about templates, during which we’ll pick out some of the more interesting templates and dissect them for your reading pleasure. This should really solidify things for those of you reading along.

We hope you’ve enjoyed this extensive insight into the Campaign Monitor template groups, and should you have any questions, please feel free to post them in the comments below.

Don’t forget the competition!

We’re running a competition in conjunction with these posts (more about that here). There is almost $3000 in fantastic ExpressionEngine licenses and modules, Campaign Monitor credits and learning materials up for grabs, so we encourage you to get involved. There are several ways you can enter, and you can enter multiple times:

  • Tweet about the series (click here or include the hash code #buildingcm in your tweet)
  • Digg any blog post in the series
  • Bookmark any blog post in the series on Del.icio.us
  • Leave a constructive comment on any post in the series
  • Subscribe to the RSS feed (click the secret link in any RSS article and leave a comment in our hidden blog post to register your entry)
  • Subscribe to the newsletter (sign-up form at the bottom of this site)
  • Forward the newsletter to a friend (you can do so after signing yourself up)
  • Write a blog post about the series and ping us

Comments

The following 23 people were compelled to have their say. We encourage you to do the same.

  1. Aaron Martin's Gravatar

    Aaron Martin said on Wednesday 18th February, 8:25pm:

    What a great series. This is going to help immensley with the 3 or so sites I’ll be building out over the next few months.

  2. Austin Siewert's Gravatar

    Austin Siewert said on Thursday 19th February, 12:42am:

    @Aaron, I concur. 

    Nice tip about the includes templates with a . at the beginning. I was unaware of that and will start using this method.  Thanks for sharing…this is very insightful

  3. Chris's Gravatar

    Chris said on Thursday 19th February, 1:09am:

    Great post! Can’t wait for the next one.

  4. Rob's Gravatar

    Rob said on Thursday 19th February, 2:06am:

    I just began using EE about five days ago and so far built an entire site in three.  I’m a convert and these are a huge help in working smarter.  Thank you!

  5. Stephen's Gravatar

    Stephen said on Thursday 19th February, 2:08am:

    Even though I’ve now done 3 EE sites, and have read numerous tutorials, these are super helpful because you explain your methodology and reasons for making the choices you did in ADDITION to how you then accomplished it.  Keep it up!

  6. Sean's Gravatar

    Sean said on Thursday 19th February, 10:07am:

    I’m also new to the .template-name for embeds and will be moving that direction on my next build.

    Will also have to re-read this entry to make sure I got everything I can.

  7. Leevi Graham's Avatar

    Leevi Graham said on Thursday 19th February, 12:44pm:

    Regarding the “.” method for hiding templates more information can be found in the ExpressionEngine documentation. There’s even a hidden configuration variable if you don’t like the dot notation.

  8. ikreknin's Gravatar

    ikreknin said on Thursday 19th February, 8:35pm:

    I’m trying to understand whether there is any sense to hide .foot, .sidebar and similar (hidden) templates in such a way. Nobody (even Google) will search templates ‘foot’ and ‘sidebar’ (w/o dot). And if somebody finds them, what can that change?

  9. Todd's Gravatar

    Todd said on Friday 20th February, 12:00am:

    I wasn’t aware of the .hidetemplate function in EE. Learn something new everyday! Thanks a bunch for the insights.

  10. Austin Siewert's Gravatar

    Austin Siewert said on Friday 20th February, 12:31am:

    @ Leevi, when setting the hidden configuration variable to “_”, will that also set the template group folders to hidden? For instance, all the includes template groups for CM start with an underscore.

  11. Steven Grant's Gravatar

    Steven Grant said on Saturday 21st February, 12:19am:

    I’m liking this series guys - keep up the excellent work

  12. Brandon Vaughan's Gravatar

    Brandon Vaughan said on Saturday 21st February, 2:05am:

    I would love to know how you managed getting rid of the category trigger segment in the blog section. Did you use the same technique as the index.php removal?

    This is a wonderful series!

  13. mdonohue's Gravatar

    mdonohue said on Monday 23rd February, 4:25am:

    Thanks for the great tutorial and all the great tips. I will start using the . in front of the include template names.  I recently downloaded solspaces tag module, but didn’t realize it could be used for creating relationships.  I have a hard time getting my brain around the out-of-the box relationship function.  I think this way might be easier for me.

  14. Tim Kelty's Gravatar

    Tim Kelty said on Tuesday 24th February, 9:16am:

    I’m curious…you have the home page, as well other templates in the ‘Pages’ template group. Are you using the Pages module to route those to your site root? (/pricing/ instead of /pages/pricing)? Otherwise, I guess you could have Strict URL’s turned off, or rewriting with Apache.

    Great series so far, thanks!

  15. Björn's Gravatar

    Björn said on Wednesday 25th February, 2:55am:

    Thanks for this tutorial. It will definitely come in handy when I start building my first EE site soon.

    I think you should know that the text-shadow property you’re using on your site actually screws up Safari 4 and Opera text rendering. As far as I know using the text-shadow in this way is supposed to enhance the text rendering, so if it doesn’t then it might be a better idea to leave it out. I’d appreciate it!

  16. Jason H's Gravatar

    Jason H said on Thursday 5th March, 12:48pm:

    Excellent post!!!

    This is the kind of stuff the ExpresionEngine Community needs!

    Keep up the good work guys!

  17. Deryk W's Gravatar

    Deryk W said on Thursday 26th March, 9:07am:

    How you have structured your templates makes complete sense. Thank you for sharing.

    When I first installed EE to test it out, I was very disappointed at the default template structure because the header, footer and sidebar were coded into each page. Not very inspiring. But your post has provided hope :)

    Could you give some examples of how you broke up the page structure. For example, a skeleton of the header, footer, index pages and entries, and where you put what.

    I’m a WordPress user right now, and will probably stick with WordPress only because of the power of Wordpress MU, which is outside of the licsnse of Expression Engine. I look forward to what EE 2.0 has to offer, but am also conscious of the rapid improvements in wordpress as well.

  18. Joel Steidl's Gravatar

    Joel Steidl said on Monday 30th March, 4:07pm:

    I’d be interested to know the planning you did up-front on this project. When I build EE sites, I like to architect a plan first that lays out everything. I wrote a blog post last week called Expediting the Expression Engine Setup Process that describes the steps we go through setting up EE.

    Great series!

  19. Kirk Beard's Gravatar

    Kirk Beard said on Thursday 16th April, 7:08pm:

    This has been a great series to read through. We’re currently doing a bit of research at work on which CMS to use for our website. I’m leaning towards EE but it’s having never used it before, it’s been a bit daunting to work out just where to begin.

    Reading through how you guys have put together the Campaign Monitor helps a lot, so thanks.

  20. reklam ajansları's Gravatar

    reklam ajansları said on Saturday 20th June, 2:38am:

    Thank you for informing us. You must be a useful follow-up issues.
    reklam ajansı
    reklam ajansları
    Bayrak

  21. kodegeek's Gravatar

    kodegeek said on Monday 27th July, 6:46pm:

    can we use normal template to send newsletter?

  22. Pflege Tester's Gravatar

    Pflege Tester said on Wednesday 18th November, 9:11pm:

    Thank you for this article, very helpful to me.

  23. Scott McCracken's Gravatar

    Scott McCracken said on Friday 4th December, 6:42am:

    I love the concept of starting a template name with a “.” if it’s not meant to be loaded in the browser.

    However, by default, TextMate hides all files from their project view that start with a period (except .htaccess).

    To change this I had to update the “file pattern” preference under: TextMate > Preferences > Advanced > Folder References

    Apologies for my rudimentary regex skills, but I changed the following bit:
    !(/\.(?!htaccess)

    to:
    !(/\.(?!htaccess|[a-z])

    That will match any file that starts with a period and a lowercase letter. I only want to show files that start with a lowercase letter because I don’t want to see all those .DS_store files.

    I was scratching my head over this for a while, hope it helps someone in the same situation.

Your comment

Please keep your comments friendly and on topic.

Your info
Your comment