Expression Engine has become a popular choice to power many sites. I have just begun experimenting with it, and I have been very impressed. One thing that I have been interested in determining was to figure out if I could set an id on the body like I do when building other sites. I have already written one article showing how to do this in PHP and WordPress, but this will show how to do it dynamically in Expression Engine.

Why are Body Ids Useful?

Body ids can be useful for styling sections differently, displaying certain parts of a dynamic template, displaying current navigation states, and many other things.

A Simple Example

Let’s say that I want to have my font size be 14 pixels, except on the homepage. It would be as easy as this:

body { font-size: 14px; }
body#home { font-size: 12px; } 

Pretty useful. By using body ids, we now have a unique hook for each section of the website.

Why not Body Classes?

I do utilize body classes as well. I typically use the body id to indicate the section, then other various items for the body classes.

For Example

For my own blog, I have some pages that I want to have a left gutter on it so that I can push images, quotes, etc. into the column. I also have another class that indicates when it is a blog article page. So, I can just continue to use multiple classes on the body to help me control the width and layout of the page.

Here is what the body element looks like on a blog article on my site:

<body id="blog" class="subpage leftGutter article"> 

The subpage class just indicates that it is not the homepage. Not completely necessary since I already have a specific id on the homepage, but it can sometimes become useful.

The leftGutter class is used to push the content area to the right and make it narrower. Then, I can pull elements into the left-hand gutter as well.

The article class is useful because some of the markup for the blog entry information is the same as the homepage and archive pages. Using this class, I can be more specific with my styles to change the way that these elements are displayed on the blog article page.

I always try and add classes and id attributes as high up in the tree as possible. This let’s me utilize descendant selectors in the CSS without having to add additional classes and ids lower down.

Setting the Body Id in Expression Engine

I want to have complete control over the body id, so I want to be able to have it set dynamically and also be able to set it statically.

So my thought behind this is that first, I want to check to see if the body id was set statically. When I say statically, I mean passing the variable in as an attribute on my embed statement. Next, I will then set the body id dynamically.

Setting the Id Statically

In order to make changes to the overall website structure simpler, I have a header template the sits in the includes template group. So in all of the other template groups, I embed the header on the page:

{embed="includes/header"} 

Then, if for some reason I want to specifically pass in a body id, I can just change it to this:

{embed="includes/header" body_id="contact-us"}

So the first step in the header is to check to see if the embed:body_id variable is set:

<body
{if embed:body_id}
 id="{embed:body_id}"
{/if}

Note: Line wrapping added for readability.

Dynamically Setting the Id

If we are not statically setting the body id, we want to then do it dynamically. My thinking is that I will take advantage of Expression Engine’s URL segments to determine which section we are in.

Here is an example of URL segments using the following URL:

http://ee.trevor-davis.com/index.php/about/me/education/ 
  • Segment 1 = about
  • Segment 2 = me
  • Segment 3 = education

Then, we can reference each segment like so:

  • Segment 1 = {segment_1}
  • Segment 2 = {segment_2}
  • Segment 3 = {segment_3}

So basically what we want to do is assign the body id the value of {segment_1} if it is not empty. So continuing on our example:

<body
{if embed:body_id}
 id="{embed:body_id}"
{if:elseif segment_1}
 id="{segment_1}"
{/if}

Note: Line wrapping added for readability.

But wait, what about the homepage? The homepage will have nothing for the value of {segment_1}, so we can just put in an else statement:

<body
{if embed:body_id}
 id="{embed:body_id}"
{if:elseif segment_1}
 id="{segment_1}"
{if:else}
 id="home"
{/if}

Note: Line wrapping added for readability.

Here is the line of code without any line wrapping:

<body{if embed:body_id} id="{embed:body_id}"{if:elseif segment_1} id="{segment_1}"{if:else} id="home"{/if}> 

I created a demo Expression Engine site to test this functionality.

View Demo Site

Walking Through the Demo Site

Since we have body ids for each section and an id on each list item in the navigation, I have created the current state for the navigation with a few simple line of CSS:

body#home ul#primaryNav li#homeNav a,
body#about ul#primaryNav li#aboutNav a,
body#services ul#primaryNav li#servicesNav a,
body#contact-us ul#primaryNav li#contactNav a {
 background: #B3602D;
 border-top-color: #B3602D;
 color: #fff;

Note: Line wrapping added for readability.

I also want to show the sidebar on all of the subpages, so I just need 1 more conditional:

{if embed:body_id || segment_1}
 <div id="sidebar">
 </div>
{/if} 

This is checking to see if {embed:body_id} or {segment_1} are not empty, and displaying the sidebar if one or both are set.

These are just a few examples of using a body id in Expression Engine, but the possibilities are endless.

One More Thing

Another thing that I was trying to figure out was how to create a variable that I could reuse in multiple embed files. So what I want to do is in my conditional statement, determine that the body id should be and assign it to a variable. Then, I want to be able to access that variable in the footer without have to use the same conditional statement.

Is this possible? I was messing around with the {assign_variable} tag, but that didn’t seem to do the job because it can only be used in the same template. Anyone know how to do this? I’m relatively new to Expression Engine, so I am still learning.