An Introduction to ExpressionEngine

26 January 2008

ee-logo.jpgPeople may refer to ExpressionEngine as a blogging application, and it’s true that the design evolved from one; but it’s much more. Underneath the hood (get it?), EE has the power to drive even most large-scale websites. If you’re looking for a reason to invest some time and effort into learning and installing it, keep reading. This article is intended for those who might already have a website, but who want to upgrade to using a content management system, or for those who might be disillusioned by their current CMS. Before continuing, you should know that I’m assuming: (1) that you know what a CMS is, (2) that you have a basic understanding of the technologies that power a CMS, and (3) that you have already explored, or at least browsed, the ExpressionEngine website and have a general idea of what it does. I don’t want you to get hung up on terminology or technical concepts and disregard ExpressionEngine as too complicated. One of the reasons for choosing EE over another content management system is because it’s easy to learn, deploy and use.

The weblog module

ExpressionEngine is modular, and is built for scaling. However, there is one primary module that could be considered the heart of the app: the “weblog” module. This module is where most content is stored and is extremely flexible. Case in point is the ability to change the name of the module itself – or, at least, the ability to put an alternate label on it. In fact, for the sake of clarity, and to underscore the dynamic range the module has, I’ll start referring to “weblogs” as “channels”.

Channels can be anything. They can be product catalogs, media archives, calendars, graphic libraries, et al. Think of a channel as a container of items, and the items as basically anything you want. ExpressionEngine allows for multiple (limitless, even) channels.

Perhaps the best way to illustrate this is by using The City Church website as an example. On our site we have multiple channels, all simultaneously available, and all accessed using the same (“weblog”) module. One obvious channel is our audio archive, where each message/sermon is an entry. Other channels contain our homepage content, small groups catalog, and online bookstore. Each channel is unique in both form and function, and, as I said, each is powered by the same module.

Field, category and status groups

If channels are the heart of EE, then groups are its arteries. Each channel has three group assignments as part of its setup: a custom field group, a category group, and a status group. These groups are separated from the channel so they may be actively accessible to other channels. This allows channels to share, say, the same categories, but still have different custom fields.

Custom field groups are comprised of … yep, custom fields. The default set of fields (Title, URL Title, Summary, and Body) are typical to a blog, but if your channel is meant to be something besides a blog, you can create new custom fields for it. For instance, for The City Church’s audio archive channel, I’ve created a custom fields that apply to a message and its audio file, such as “Speaker”, “Campus”, “Service Time”, “File ID” etc. (Read more on how the audio archive is powered.)

Category and status groups are basically the same. Statuses, though, play an important role as they have the ability to control an entry’s ranking or position.

More on groups can be found in the exhaustive ExpressionEngine documentation.


You can think of templates in ExpressionEngine just like web pages. In their simplest form, that’s all they are. Keeping the same analogous theme, templates could be considered the skin of an EE-powered website … beautiful, external, and flexible; yes, that works.

ExpressionEngine’s templates are what makes it so unique, but they’re also where most newcomers to EE get stuck. I think the flexibility they offer is, ironically, where the confusion comes in. Templates in EE lack the rigidity found in other CMSs. Instead of having a clear and obvious framework, EE’s templates allow you to think outside the box when architecting. The concepts are strange at first, however, the system is forgiving enough that when you finally get a handle on how it all works you’ll wonder how you ever did dynamic websites before.

The first thing to understand with EE templates is that they’re stored in the main, MySQL database, and are not actual files. (There is a caveat to this, though, because EE does let users save templates to the server as files.) Actually, when visitors browse an EE-powered website, they’re only ever accessing one file: index.php. That one file is able to reference the whole of the system, including templates, modules, and plugins.

Templates are grouped into “template groups”. Template groups are more than just organizational, and can be extremely versatile in function – more on that later. First, let’s look at the ExpressionEngine URL structure, and how template groups and templates come into play:

After the domain is the index.php file I mentioned. Again, that one file is the key to engaging the EE system. Once EE is invoked, it takes the URL request, and breaks it down; first looking for a template group, then an individual template. This URL structure is “human-friendly” (versus, say,, and also search engine optimized.

The tendency is to think of templates and template groups as files and directories – and that’s just what the EE documentation suggests – but that might lead to more frustration than anything else. I prefer to think of template groups as “topics” or “themes”, and templates as “functions”. I think of them this way because templates can be embedded into other templates, and template groups represent more than just groupings of templates.

When building a site in EE, you can use individual templates for each screen your visitors will see, or, if you’re clever, you could build one template – a Lord of the Rings type thing; one template to rule them all. How, you ask? Through the power of URL segments.

URL segments, global variables, and other such trickery

I mentioned that one of the primary reasons to choose ExpressionEngine is because it’s easy to learn, deploy and use; and that’s true. But the main reason I use it is because of its power and flexibility – most of which is found in features exclusive to EE.

The first such feature is URL segments. As I’ve illustrated previously on my blog, URL segments can be extremely useful when coupled with templates. Since ExpressionEngine is essentially taking over the job of serving a website (from the server itself), it also actively processes URL requests, no matter how long, and breaks them down into what are called segments. So in our example above, EE would see the URL and assign {segment_1} as “template_group” and {segment_2} as “template”. It’s not hard to imagine how beneficial having that kind of association can be. I’ll give you an example.

Let’s say you’ve been asked to make some changes to the “About Us” section of a website. No, problem, right? Just pull up the “about” template, make the changes, and hit “Finished”. But what if, before the changes are published, you have to get them approved? You could create a new template, call it “about-preview”, and copy/paste the “about” template in, make the changes, and send the new URL to your client for approval. Or, by using URL segments, you can make it much easier and transparent. You’d just open the “about” template, wrap the changes in a conditional statement – {if segment_3 == "preview"} – and tell your client to add “/preview” to the end of the URL.

We can even take this example further, and apply some other cool ExpressionEngine features like global variables, member groups, and plugins.

To protect the changes from prying eyes, you could also require your client be logged in before viewing the changes. You’d do this by changing the conditional statement to {if logged_in AND segment_3 == "preview"}. Or you might want to make sure only they can see it, not another logged in member: {if username == "client_name" AND segment_3 == "preview"}. Even better, let’s make an idiot-proof link they can click to see the changes:

{if username == "client_name" AND segment_3 == ""}<a href="{path=template_group/about/preview}">Click here to see changes</a>{/if}

To show your client that they are, in fact, viewing the latest revision of changes, you could include a time-stamp, showing the time the “about” template was last edited: (Edited: {template_edit_date format="%%F %d, %Y at %h:%i %A"}), which would render as “(Edited: January 26, 2008 at 4:53 PM)”. You could even include the time since they last visited by employing a third-party plugin called “Since Last Visit”.

Can you see how powerful (and even fun) ExpressionEngine can be?

Flexibility at a premium

What makes ExpressionEngine so flexible could also be considered its greatest weakness. That you have to edit and save templates inside a web browser makes for a terrible development workflow. Who wants to write code in a text area field? Yes, there’s a way around it, but even that method comes with its fair-share of issues. It’s peculiar, but I believe the template model itself, though versatile and dynamic, is the Achilles heel of ExpressionEngine.

Start your Engines

Despite some small flaws, ExpressionEngine remains a highly capable, extremely flexible website CMS solution. Even the free, Core version packs enough punch to handle a typical blog or small site. I’ve been using it since version 1.0 (actually, since pMachine Pro), and I continue to be amazed and inspired by each new release.

If you’re considering making the switch, I hope you found this quick introduction motivating enough to get started. I suggest you take the next step and download the Core version. You should also browse the documentation and Knowledge Base, both of which are well-maintained and written.

In addition, the EE Forums remain the best resource for learning ExpressionEngine, hands down. The support community on the forums is responsive, helpful and passionate.

You might also be interested to know that some highly respected designers and studios already use ExpressionEngine; Happy Cog, for example. Others include:

So, to answer the most-oft question I receive via email: yes, I highly recommend ExpressionEngine [affiliate link].