Using Templates to Display Channel Content in ExpressionEngine

Leonard Murphy

September 2010


Building Websites with ExpressionEngine 2

Building Websites with ExpressionEngine 2

A step-by-step guide to ExpressionEngine: the web-publishing system used by top designers and web professionals everywhere

  • Learn all the key concepts and terminology of ExpressionEngine: channels, templates, snippets, and more
  • Use RSS to make your content available in news readers including Google Reader, Outlook, and Thunderbird
  • Manage your ExpressionEngine website, including backups, restores, and version updates
  • Written in an easy-to-follow step-by-step style, with plenty of examples and exercises

Read more about this book

(For more resources on ExpressionEngine, see here.)

Creating templates

To start with, build two templates: one for the CSS stylesheet and one that contains the HTML that defines the page structure and brings in your channel content. Since the CSS template will be used all over your website, it makes sense to put this in a separate template group called includes (which you will create).

For the page itself, use the index template in the site template group.

  1. In the control panel, click on Design | Templates | Template Manager from the top menu. Then select the New Group button, located above the list of existing template groups.

  2. Call the new template group includes. Do not duplicate a group and do not make the index template your site's home page. Click Submit.
  3. Back on the Template Management screen, make sure the includes template group is selected, and then click on New Template.

  4. Call the new template site_css and select a Template Type of CSS. Leave the radio button checked to create an empty template and click Create and Edit.
  5. From the Ed & Eg site that you downloaded and extracted earlier, open style.css in a text editor such as Notepad. Copy and paste the entire file into the includes/site_css template and click on Update.
  6. Within the stylesheet, there are several references to images in the image directory. For the style to render properly, you will also need to upload all the images in the /images sub-directory (including money.jpg) to the /images sub-directory on your website.
  7. After uploading all the images, you will also need to update the paths in the stylesheet to point to this sub-directory. Within the site_css template, wherever you see url(images/imgxx.jpg), change it so that it reads url(http://localhost/images/imgxx.jpg) (replacing http://localhost/ with your website domain if you are not using a localhost environment). There should be 10 replacements in total (one for each image). When you are done, click on Update and Finished.
  8. Next, on the Template Management screen, highlight the site template group and then select the index template.
  9. If you do not have such a template group and template then go ahead and create it now.

  10. Delete everything currently in the template.
  11. Open index.html of the static Ed & Eg website in a text editor such as Notepad. Copy and paste the entire source code into the template.
  12. Since the stylesheet is no longer located in style.css, this path needs to be updated. To do this, use the ExpressionEngine stylesheet variable to indicate the includes template group followed by the site_css template that the CSS stylesheet is in. Change the line:

    <link href="style.css" rel="stylesheet" type="text/css"
    media="screen" />

    to read:

    <link href="{stylesheet=includes/site_css}" rel="stylesheet"
    type="text/css" media="screen" />

  13. Finally, click Update to save the template and browse to http://localhost/site to view the output of the template as it stands right now. It should look identical to the static index.html page (except that in ExpressionEngine, none of the links will work because you have only created one page so far).

If you did not hide your index.php file as part of installing ExpressionEngine, remember that your ExpressionEngine URLs will include the additional index.php (for example, http://localhost/site will become http://localhost/index.php/site for you).

Did you spot the deliberate mistake? Although, at this point, everything looks good, the content being displayed in this URL is not from your channel at all, but is what you copied and pasted from the index.html file into your site/index template. The next step is to replace this static content with the content from the website channel.

Pointing your template to your channel

Pointing your template to use your channel content is the step that links together everything you have done so far (creating custom fields, creating the channel, publishing content to the channel, and creating templates).

  1. In the control panel, click on Design | Templates | Template Manager from the top menu. Then select the site template group and click to edit the index template.
  2. Delete all the code from after the <div id="content"> tag to the closing </div> tag (leave these two tags in place though).
  3. Underneath the <div id="content"> line, add the following. This code says that you would like to display content from the website channel (but only one entry and only the entry with a URL title of welcome_to_our_website).

    {exp:channel:entries channel="website" limit="1" url_

  4. Next, add the following line. This says that you no longer want content from the website channel.


  5. In between the opening {exp:channel:entries} and closing {/exp:channel:entries} tags, add the following code. This displays the title from your entry as an <h1> header.


  6. Underneath the title, add the following code to place the image from your channel entry onto the page. The {if website_image} statement means that if there is no image defined in the channel entry, do not display the img code at all.

    {if website_image}<img src="{website_image}"
    class="left" />{/if}

  7. Finally, add the following tag to display the content of your content field:


  8. The content section should now look like:

    <div id="content">
    {exp:channel:entries channel="website" limit="1" url_
    {if website_image}<img src="{website_image}"
    class="left" />{/if}
    <!-- end #content -->

  9. Finally, update the page title to reflect the entry title. To do this, replace the line <title> Ed & Eg Financial Advisors </title> with the following code. Although it looks complicated, it's actually the same as the }exp:channel:entries} code in the steps above, except that all you are displaying is the {title} field and not any of the other custom fields you created.

    By default, the {exp:channel:entries} tag requests a lot of information from your database, which can increase the amount of time it takes to display your page. Since you are only displaying one field, the disable parameter tells ExpressionEngine not to request other information you know you do not need (including the data in your custom fields). For more information on this parameter, you can visit

    <title>{exp:channel:entries channel="website" limit="1"
    url_title="welcome_to_our_website" disable="categories|category_
    exp:channel:entries} - Ed &amp; Eg Financial Advisors</title>

  10. Click Update to save your changes and then browse to http://localhost/site to view your updated website. If everything is well, then you should not notice much difference at all, but behind the scenes, your content is now coming from your channel entry, rather than being part of your template.

Read more about this book

(For more resources on ExpressionEngine, see here.)

Adding more pages

So far you have created a new channel with custom fields, posted to the new channel, and created a template to display your channel content. However, you have not yet seen how to manage multiple pages.

The most obvious solution to having multiple pages is to create a template for each page that is an exact copy of the template you already have, except with a different url_title channel parameter so that the template fetches a different channel entry. For example, the individual/index template would request the Individual/Family channel entry.

The downside to this solution is that you would end up with multiple templates all containing much of the same code. While this is fine when the code is not changing, if (for example), you wanted to adjust something on the page (such as the sidebar), you would have to update multiple templates.

To get around this repetition, you can use embedded templates. Embedded templates are templates that are included within another template. The included template can be a small piece of code (such as code to display breadcrumbs) or can be an entire HTML page. Embedded templates can accept variables, allowing you to alter the output of the embedded template dynamically.

In the following steps, you will create a hidden embedded template that is a copy of the template you have just created. However, instead of having the url_title of the entry you want hardcoded into the template, it will instead be a variable. You will then change your site/index template so that instead of it building the HTML page itself, it will simply call the embedded template and pass in the URL title welcome_to_our_website as the variable. Once you have done this, there is no limit to how many templates you can create to display different entries from your channel.

This solution still requires you to create a template each time you want to add a static page to your website, but instead of each template containing the entire HTML to construct the page design, each template will only include a few lines of code to call the embedded template and display the required entry.

There are actually many ways of handling static content within ExpressionEngine, of which this is just one example.
Another good option is the free Pages module: this first-party module allows you to override the standard URL structure (of http://localhost/tempate_group/template) and instead manually set a channel entry to appear at any URL you choose, using any template of your choice. In this way, you can use one template to display different channel entries at different URLs.
Michael Boyink has also written several tutorials on building both two and three-tier static content in ExpressionEngine without using add-ons like Structure or Pages, and this is done in a way that allows you to add new pages without having to create a corresponding template. These can be found at

Begin by creating an embedded template and pointing your existing site/index template to embed this template instead:

  1. In the control panel, click on Design | Templates | Template Manager from the top menu. Select the includes template group on the left-hand side and then select New Template on the right-hand side.
  2. Call the new template .website_page. The preceding period indicates this template is hidden (meaning that a visitor to your website or a search engine spider cannot see the output of this template directly at the URL http://localhost/includes/.website_page).
  3. You can also use an underscore at the beginning of a template name to mark the template as hidden.

  4. Leave the template type as Web Page. Under Default Template Data, select Duplicate an existing template. In the drop-down list of templates, select site/index as the template to duplicate. Click on Create and Edit.

  5. In the new template, there are two places where you can see the {exp:channel:entries} parameter url_title="welcome_to_our_website"—one at the top of the page in the <title> tag and one at the start of the content section. Change both these parameters to read url_title="{embed:url_title}" instead. This says to use the variable for url_title that is passed in from the calling template. Click on <b> Update and Finished.
  6. Now edit the site/index template and delete everything in it. Instead, add just this code (to call the embedded template includes/.website_page with a variable url_title set to welcome_to_our_website).

    {embed="includes/.website_page" url_title="welcome_to_our_

  7. Click on Update and Finished and now visit http://localhost/site. Even though your updated site/index template is much shorter than before, notice how the web page itself looks no different.

That's it! The design is now such that you can have as many static website pages as you like, each of which use the same embedded template. Now all that is left to do is prove this works by creating a second page.

Publishing a second page

There are two steps to carry out every time you want to create a new static website page. First create a channel entry with the content for the page and then create a template group and edit the index template to embed the .website_page template with a URL title of the channel entry you wish to display.

If you wish to have a static second tier page (such as a URL of business/news), then you would create a template called news in the business template group and then embed the .website_page template as you normally would.

To demonstrate how this works, create a second channel entry. This time, it should be based on the individual.html page in Ed & Eg's website.

  1. Open the downloaded individual.html page in your browser.
  2. In the control panel, select Content | Publish | Website. Use a Title of Individual/Family and a URL Title of individual_family.
  3. Under Image, select Add File. However, this time, instead of having to upload the same image again, you can click on Main Upload Directory on the left hand-side of the File Manager and click on the previously uploaded money.jpg.

  4. Then, as before, copy the content from the Individual/Family page in your browser, marking up the headings as <h2>. For the hyperlink in the How Much Do We Cost? section, use a hyperlink such as <a href="{site_url} promotion" title="Promotions">promotions</a>, which will resolve to http://localhost/promotion in anticipation of you creating the Promotions page at that URL. When you are done, click Submit.

The {site_url} variable is a global ExpressionEngine variable that substitutes itself with the URL to the root directory of your website (as defined in Admin | General Configuration). The benefit of using this ExpressionEngine variable, instead of typing in the (much longer) root directory of your website (such as http://localhost/), is that if you ever change your website domain, you only have to change it in one place in ExpressionEngine (rather than changing every occurrence of the domain name.)

Now that there is a second channel entry, we can go ahead and create a template for it.

Creating a second template

Call the new template group individual so that its output appears at the URL http://localhost/individual.

  1. In the control panel, click on Design | Templates | Template Manager from the top menu. Select New Group on the left-hand side.
  2. Call the new group individual. Then, under Duplicate an Existing Template Group?, select the site template group to duplicate. Click Submit.
  3. Edit the index template of the individual template group and change the code to read as follows:

    {embed="includes/.website_page" url_title="individual_family"}.

  4. Click Update and Finished and visit your new page at http://localhost/individual to verify it. It looks identical to the individual.html page from Ed & Eg's static website.
  5. Verify that the promotions link you created in the entry links to http://localhost/promotion. Although you have not yet created that page, if the link appears as http://localhostpromotion, it's likely the URL to the root directory of your website doesn't include the final forward slash (for example, it might be set as http://localhost instead of http://localhost/). To change this, go to Admin | General Configuration and update the setting called URL to the root directory of your website.

By now, you can see that the website is relatively easy to maintain. To create a new page, all you need to do is create a new channel entry and a new template that references the URL title of your new entry. To change the wording or the image on an existing page is even easier; all you have to do is edit the entry. No dealing with templates or template code at all! Finally, should you ever wish to change the site design, you only have to do so in a single template.

Going live

Currently, unless you have already changed this, the default template group is the Agile Records website (news/index), meaning that if you go to http://localhost/, the news/index template will be rendered. (If you didn't install Agile Records and didn't already define a default template group, then visiting http://localhost will display a blank screen). Change the default template group to be site/index (which is where the Welcome to Our Website entry is displayed). Follow these instructions:

  1. To change the default template group, go to Design | Templates | Template Manager in the control panel.
  2. Highlight the site template group on the left-hand side and then select Edit Group (the left-most button above the list of individual templates).

  3. Check the box that says Make the index template in this group your site's home page? and click Update.

  4. Now, when you visit http://localhost/, you should see Ed & Eg's website in place of Agile Records.

Note that you can still access the Agile Records website at http://localhost/news. If you are following along on your own computer, this allows you to refer to the Agile Records site at any time. However, if you are on a live web server, you may wish to suppress the Agile Records website completely. You can do this in Template Manager—next to each template associated with Agile Records (about, global_embeds, news, search), there is an option called Access. You can change the access for each template to say that visitors to your website cannot view the output of these templates, but that instead they should be routed back to the site/index template. (You and other SuperAdmins will still be able to see the template output at their current URLs. So if you wish to verify that the re-direct is working, you must first log out of ExpressionEngine).

Read more about this book

(For more resources on ExpressionEngine, see here.)

Avoiding repetition

You have already created an embedded template that saves you from having lots of templates with the same basic HTML code inside. When working with templates in ExpressionEngine, it's best to avoid code repetition of code as much as possible— whether the repetition is within a single template or across multiple templates.

Any situation where code is repeated can be a major headache, should you ever wish to update that code; instead of being able to make an update in a single location, you instead have multiple places to make the same update, increasing the likelihood that you miss one. On a small site with only one or two templates, it's easy to manage code that is repeated, but as your site grows, having the same code in more than one template can make changes very difficult and time-consuming to accomplish.

ExpressionEngine has four ways to reduce repetition:

  1. Preload text replacements
  2. User-defined global variables
  3. Snippets
  4. Embedded templates

Each of these methods involve assigning the repeated code to a custom ExpressionEngine tag and then using that tag whenever you want to use the repeated code in a template.

The key differences between these methods are:

  • Preload text replacements only work within the same template and can only contain a string (no ExpressionEngine tags).
  • Global variables can contain a single line or multiple lines of static HTML and text—in fact, anything except ExpressionEngine tags and code.
  • Snippets are identical to global variables, except that snippets can contain ExpressionEngine tags.
  • Embedded templates, as you have already seen, are an entirely separate template that can be included in another template.

For performance reasons, it's best to use the first available option that will meet your needs. If the text is a string that is only being repeated in a single template, use Preload text replacements. If your code is repeated in more than one template, but does not contain ExpressionEngine tags, use global variables. If the repeated code includes ExpressionEngine tags, use snippets. Embedded templates are usually only necessary in special circumstances such as when you want to use variables to dynamically vary the code that results (a snippet cannot be passed variables).

You have already seen how powerful embedded templates can be. What follows are examples of the other tools.

Preload text replacements

Preload text replacements are useful as local constant variables. In ExpressionEngine, you will find that there are certain references that are made multiple times within a single template, such as the channel where the main content is coming from or the template group that the template is in. By creating Preload text replacements for these references, you can gain several benefits:

  • It gives you a single place in each template to change one of these references, should one of the names ever change.
  • When creating a new section of your website, you will often start with an existing template as a base. If the existing template has Preload text replacements, you can simply copy the existing template and change those preload replacements, saving a lot of time.
  • The Preload text replacement may be shorter to type (although if it's not, it is still sometimes a good idea to use a Preload text replacement than have repetition).

For the remainder of this article, each template you create will have a Preload text replacement called my_channel for the channel that the template references the most. By doing this, it will save you from having to constantly remember what the channel short name is; you will simply set it at the top of each template and then use {my_channel} instead.

Go ahead and create a {my_channel} Preload text replacement in the includes/. website_page template now.

  1. Edit the includes/.website_page template. At the very top of the template, insert the following code:


  2. In this template, there are two places where you can see the {exp:channel:entries} parameter channel="website"—one towards the top of the page in the <title> tag and one at the start of the content section. Change both these parameters to read channel="{my_channel}" and click on Update.
  3. Visit your website and you should see no difference in the content. (If the content has suddenly disappeared, there may be a misspelling).

User-defined global variables

User-defined global variables can be used for any code that is repeated and that does not contain ExpressionEngine tags. Unlike Preload text replacements, a global variable can contain multiple lines of text and can be used in any template. The site name at the top of each page is a good example of this—although it's only three lines and it does not contain any ExpressionEngine tags. However, it will be needed in every template, so it's worth extracting into a global variable. This way, if Ed & Eg ever change their site name, the update only has to happen in one place and the entire website will be updated.

  1. In the control panel, select Design | Templates | Global Variables from the top menu.
  2. You will see that there are already some global variables that have been defined. These are being used by the Agile Records website. Click on Create a New Global Variable at the top right.
  3. Call your new variable website_sitename.
  4. The variable content will be as follows.

    <div id="logo">
    <p class="sitename">Ed &amp; Eg Financial Advisors</p>

  5. Click Update to save the global variable.

  6. Now go back to the includes/.website_page template and replace the section of code that displays the site name, starting with <div id="logo"> down to and including the corresponding closing </div> with the global variable tag {website_sitename}. When you are done, the two lines of code after <div id="header"> should look as follows. Click Update.

    <div id="header">
    <div id="menu">

  7. Visit your website and you should see no difference. Reducing repetition is something that makes the website easier to maintain for you, but does not change anything for your visitors.


Snippets are ideal for code that is repeated and that contains ExpressionEngine tags. For this example, you will convert the sidebar that appears on the right-hand side of each page into a snippet. Although the sidebar does not currently have any ExpressionEngine tags, meaning you could use a global variable, you will be adding additional functionality into the sidebar as you progress through the article. In anticipation of this, it therefore makes sense to convert the sidebar into a snippet, rather than a global variable.

  1. In the control panel, select Design | Templates | Snippets from the top menu.
  2. You will see that there are already some snippets that have been defined for the Agile Records website. Agile Records uses snippets prefixed with global for items that appear on every page (like the footer) and snippets prefixed with the template group name for items that only appear in templates in that group. We are going to create a new snippet, so click on Create a New Snippet at the top right.
  3. Call your new snippet website_sidebar, using website instead of global to distinguish this snippet from the Agile Records snippets.
  4. To save typing, copy the following code from the includes/.website_page template:

    <div id="sidebar">
    <p>From now until the end of the year, Ed &amp; Eg are
    offering a <strong>free</strong> initial 90 minute consultation,
    plus <strong>25% off</strong> your first return visit. <a
    href="promotion.html">Learn More&hellip;</a></p>
    <h3>Key Services</h3>
    <li>-Debt Management</li>
    <li>-Financial Planning</li>
    <li>-Tax Services</li>
    <li>-Book-keeping &amp; Cash Flow</li>
    <li>-Accounts Preparation</li>
    <li>-Payroll Services</li>
    <!-- end #sidebar -->

  5. Before saving this snippet, update the link that appears in the Promotion! box from promotion.html to {site_url}promotion. (Although you have not yet created a promotion template group and a corresponding website channel entry, when you do, this link will work).
  6. Click on Update and Finished to save the snippet.

  7. Now go to the includes/.website_page template and replace the sidebar code you just copied into the snippet with the snippet tag {website_sidebar}. The four lines after should now look as follows. When you are done, click Update.

    <!-- end #content -->
    <div style="clear: both;">&nbsp;</div>
    <div id="widebar">

  8. If you now visit your website, you should not see much change. The only difference that indicates the sidebar is now coming from your snippet rather than from the template is the link in the Promotions! box that points to http://localhost/promotion instead of promotion.html.

Creating a menu

Another good candidate for a snippet is the site menu that appears at the top of every page. Creating the menu as a snippet (rather than a global variable) allows you to use the ExpressionEngine variable {site_url} in place of your domain name, just like you did when creating the link to the promotions page within the Individual/Family entry.

Although you have not yet created all the entries (and template groups) for the following page links to work, you can create this menu snippet in anticipation of creating the corresponding pages later.

  1. In the control panel, select Design | Templates | Snippets from the top menu and click on Create a New Snippet at the top right.
  2. Call your new snippet website_menu.
  3. Type in the following code:

    <div id="menu">
    <li><a href="{site_url}">Homepage</a></li>
    <li><a href="{site_url}individual">Individual/Family</a></li>
    <li><a href="{site_url}business">Small Business</a></li>
    <li><a href="{site_url}contact">Contact Us</a></li>

  4. Click on Update and Finished to save your new snippet.
  5. Now go to the includes/.website_page template and replace the menu code that starts with <div id="menu">, till the closing </div> with the snippet tag {website_menu}. When you are done, the <div id="header"> section should look as follows. Click on Update.

    <div id="header">
    <!-- end #header -->

  6. If you now visit your website, you should see that your menu links have all changed. Verify that you can successfully click between the Homepage and the Individual/Family pages you have already created.

Embedded templates

You have already seen an example of an embedded template. An embedded template can do everything a snippet can do with two main differences:

  1. Embedded templates can be passed variables, and the output can then vary based on those variables.
  2. An embedded template is a template. ExpressionEngine has many different options that can be defined on a per-template basis (different templates can have different access controls, different caching preferences and different PHP settings) whereas snippets have the same settings as the template they are in. Furthermore, you can restrict certain template groups so that other administrative control panel users cannot see them, but with snippets, you can only give other administrative control panel users access to all snippets or none of them.

Note that when using embedded templates, you can define as many or as few variables as you wish. Simply listing the variables and their values in the tag creates the variables, for example, {embed="template group/template" variable1="dog" variable2="cat"}. If you do not want any variables, then the tag is simply {embed="template group/template"}.

Now that you have seen examples of Preload text replacements, global variables, snippets, and embedded templates, you can certainly go further and extract even more repeated code into these tools. The page footer could be a global variable, as could the widebar.

However, it is important to strike a balance between reducing repetition and writing code that you will understand a year or two later. Although only you can know where that balance lies for you, here are some recommendations:

  • Keep custom tags descriptive as to what the code is that they represent (for example, instead of {widget}, use a name that makes it obvious to you what the tag represents).
  • As you start out, avoid putting opening tags (such as a <div>) into a global variable, snippet, or embedded template, without the corresponding closing tag (such as a </div>). While ExpressionEngine does allow this, it can make the template code more difficult to troubleshoot.

    As you grow more experienced, there can be cases when your website page requires certain elements in a certain order simply to build the layout, so you may find it more efficient to replace a series of opening <div>'s with a global variable and then create a second global variable for the corresponding closing </div>'s.

  • Do not bundle unrelated parts of your page into the same global variable, snippet, or embedded template. While you could use one snippet for the entire footer, including the FAQs and the copyright notice, it would cause problems if, on one page, you only need the copyright notice, but not the FAQs.

For an example of just how far you can take these techniques, check out Derek Jones' official ExpressionEngine blog series 'Behind the Curtains' that talks about how EllisLab uses ExpressionEngine on their own websites. (Note that the series was written in 2007, before snippets existed):

Create a 404 Page not found

A 404 Page is an essential part of any website, and working through this article, you may have noticed that your 404 page is still themed like the Agile Records website. In this section, you will take advantage of all the repetition-reduction you have done as you create a new 404 page.

  1. Select Design | Templates | Template Manager, select the Includes template group, and then select New Template. Call the new template 404. The Template Type will be Web Page, select Duplicate an Existing Template, and finally select the includes/.website_page template to copy from. Click on Create and Edit.
  2. Since the 404 Page content does not come from a channel, delete the line that reads {preload_replace:my_channel="website"}.
  3. Change the <title> line to:

    <title>Page Not Found - Ed &amp; Eg Financial Advisors</title>

    Replace everything from <div id="content"> to <!-- end #content --> with:

    <div id="content">
    <h1>Page not Found (404)</h1>
    <p>The page you were looking for does not exist. There
    may be a spelling mistake in the URL in the address bar, or we may
    have removed this page inadvertently. Please use the menu at the
    top to visit a page that does exist.</p>
    <!-- end #content -->

  4. Click Update to save the changes.
  5. Now that you have a 404 Page that is consistent with your site design, you can define this page to appear when a page is not found. Select Design |Templates | Global Preferences from the top menu.
  6. Under 404 Page, select includes/404 as the template to display. At the same time, make sure Enable Strict URLs is set to Yes (or your 404 Page will not work). Click Update.

Now, when you visit an invalid URL (such as http://localhost/toast), you will see your 404 page instead of the Agile Records 404 page.

Templates as files

While working with templates within the web-based control panel interface works well, it does have limitations. If you are used to coding HTML files using your favorite text editor, you may wish to continue using that text editor and FTP the files to your website instead. In ExpressionEngine, this is entirely doable.

  1. If you are following along on an actual website, you will need to ensure that the directory permissions for /system/expressionengine/ templates are set to 777. If you are using a localhost environment, this is not necessary. This directory is where your template files will be saved.
  2. In the control panel, select Design | Templates | Global Preferences from the top menu.
  3. Set Allow Templates to be Saved as Files to Yes. The likelihood is that the Basepath to Template File Directory is already set to the full server path for /system/expressionengine/templates, but if it is not, you will need to set it.
  4. Click Update to save your changes.
  5. Although this option allows you to start creating templates as files, it does not automatically go back and create files for your existing templates. To do this, you have to mark each template to save as a file. Edit each template in the site, individual, and includes template groups in turn, check the box marked Save Template as File (just above the Update button), and then click Update and Finished.

  6. You will now see your template files in system/expressionengine/templates in a sub-directory called default_site.

You can now edit your template code by editing these files directly. You can easily create new templates and new template groups without using the control panel by putting new files and directories in this directory. When creating new templates and new template groups, there are certain conventions to be aware of: template groups are separate directories with the name of the group followed by a .group extension. Webpage templates end in .html and CSS templates end in .css.

You can edit templates in the control panel and in the files interchangeably. When opening a template in the control panel, ExpressionEngine will look to see if the file is newer than the database version, and if so, load the file. Updating your template will then update the ExpressionEngine database and file simultaneously (unless you uncheck the box to save it as a file).

Know that when displaying pages to visitors, ExpressionEngine will always use the file before using the template saved in the ExpressionEngine database. This means that you can feel confident updating the files outside of the control panel, knowing that the changes will immediately reflect on your website.

Occasionally, when using templates as files, you may find that a file for a template has gone missing. ExpressionEngine has a utility to synchronize the templates periodically to ensure that the templates in the database match the content of the files and that there are files for every template. To run this, you can go to Design | Templates | Synchronize Templates. The screen will summarize whether the templates are in sync or if the files are newer than the database templates. If any are not in sync, check which templates you want to sync and click on Submit to update the database with the updated files (as well as recreate any template files that may have accidentally gone missing).

For more information on templates as files, see the ExpressionEngine documentation at


These challenges are designed to stretch your knowledge and get you to work handson with ExpressionEngine. The answers will not necessarily be found within the article, but with the knowledge gained from the article, plus the ExpressionEngine documentation, you should have all the tools you need at your disposal to figure them out.

In this article, you only created the home page and the Individual/Family page. Go ahead and create the Small Business, Contact Us, and Promotions page.


In this article series, you have seen how to build a complete website using ExpressionEngine. You have taken advantage of many of ExpressionEngine's features to reduce repetition and make your website as simple to maintain as possible.

Further resources on this subject:

You've been reading an excerpt of:

Building Websites with ExpressionEngine 2

Explore Title