Our Optimal ExpressionEngine Install

January 3, 2011

We developed our CMS, HiFi, in a way that best fits our clients’ needs. However, occasionally, it just isn’t possible to use a hosted solution for a client — particularly educational institutions and some government organizations. When our clients need a self-hosted content management solution, we rely on ExpressionEngine. As people who obviously have strong opinions on content management, we respect the way EE works and the ideas behind it.

We are very particular about our work — our projects must be written to the highest standards using W3C compliant markup and, at the same time, still remain completely faithful to the project’s original design. This is certainly not an easy task, and we require that any CMS we use makes this possible.

This post explains how we set up ExpressionEngine, from hosting, to plugins, to client hand-off.

ExpressionEngine Control Panel

ExpressionEngine is a mature and extensible content management system from EllisLab that is installed on your own web server. It is very customizable and allows us to develop and launch websites that are standards compliant and true to their original designs. We also like ExpressionEngine for its:

  • Mature plugin marketplace
  • Easy, clean templating system
  • Custom field sets
  • Customizable UI for client users

Although ExpressionEngine is perfectly capable on its own, we believe it is important to extend ExpressionEngine with several very useful third-party plugins. These plugins extend the functionality of EE, but perhaps more importantly, they critically improve your clients' user experience:

We’ll go into detail for each plugin below.

It’s important to remember the cost of these plugins in addition to the cost of ExpressionEngine when quoting projects for a client. For a commercial site, this comes to $299 for EE plus $164.90 for plugins, for a grand total of $463.90. When working with clients on a tighter budget, we will sometimes spread the cost out with their hosting payments during the first year. This comes to about $39 a month on top of hosting and backup.

Of course, ExpressionEngine does have its shortcomings when compared to a hosted content management solution: ExpressionEngine requires you to obtain a hosting account, create a database, install the CMS, add and configure plugins, harden security settings, optimize the website templates, and prepare the CMS for client users.

As I’m sure most ExpressionEngine developers will agree, setting up an ExpressionEngine website is not always a simple or quick task. But when done well, the end result is very rewarding. This article explains New Media Campaigns’ process for launching a custom website using an optimized ExpressionEngine installation. We’ve found that it takes an hour or two to get up and running and then another hour to prepare the CMS for client handoff.

Starting a Project

Before we start a project, we make sure the required software and tools are available on the production server. If you don’t check these early in the project development cycle, you are in for a rude awakening just prior to launch!

We rarely develop a project on the production server, so not having these items does not impede development (assuming your development environment has them). But you should check these items before you begin development to avoid complications when your deadline looms.

Web Server

We prefer a UNIX or Linux production box (or virtual machine) running the Apache web server. Other web servers like nginx or IIS will work, too.


You’ll need a way to upload ExpressionEngine and change file permissions. SFTP access is a must. SSH access is even better.


You’ll need MySQL 4.1 or newer. Make sure your MySQL database user has SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, and DROP privileges. These are required by ExpressionEngine.


You’ll need PHP 5.0 or newer with at least 16M of allocated memory. PHP will also need the GD2 or ImageMagick libraries if your application will use CAPTCHAs, image resizing, or image watermarking.

Installing ExpressionEngine

Installing ExpressionEngine goes smoothly once you’ve got your server environment set up. The EE site documents this well. There are five steps followed by an automated installation wizard.

ExpressionEngine Plugins

After ExpressionEngine is installed, the first thing we do is complement ExpressionEngine’s default features with several helpful plugins.

Structure ($65)

Structure is perhaps our favorite ExpressionEngine plugin. It provides a different (and more intuitive) paradigm for separating content from presentation compared to what ExpressionEngine provides out-of-the-box. The Structure plugin presents website content to our clients as a tree outline; it makes it easy to understand, add, edit, and remove site content. This is a concept we believe very strongly in which is why we use it in HiFi.

We’ve found that clients have a much easier time finding and editing their own content using this type of content representation. It matches the way they think about their site and the way we collaborate with clients to build a sitemap as a part of our creative process.

NSM Better Meta ($49)

Search engine optimization is very important to our clients, as it should be. The way a site performs in search engines and delivers returns to a client’s bottom line is a key way that we are measured as web professionals.

Leevi Graham’s Better Meta plugin provides an easier, more intuitive way for our clients to enter metadata (Title, Description, Keywords, etc.) for EE site content. Important SEO fields are added to the Publish Form where they really belong. Additionally, this plugin also automatically generates a sitemap.xml file for Google and other search engines.

WygWam ($35)

Although our developers prefer Markdown for writing page content, it is silly to assume our clients do, too. Most of our clients are familiar with and prefer using Microsoft Word and we want to make it as frictionless as possible for them to control their site. Therefore, it is very important to provide a familiar in-browser experience, integrated into the CMS, that makes a best effort to produce standards compliant markup.

WygWam, a plugin by Pixel and Tonic, does just that. WygWam integrates the popular CKEditor with ExpressionEngine and allows our clients to edit pages and other content using an in-browser rich-text editor akin to Microsoft Word.

FreeForm and FreeForm Spam (Free)

Many of our clients’ websites use online forms to collect all kinds of information. It is important that the CMS be able to collect and store user-submitted information. ExpressionEngine provides a very simple Contact Form implementation out-of-the-box. But FreeForm, a plugin by SolSpace, does a much better job.

FreeForm allows us to define an unlimited number of Form variables and Form templates that are used to capture user-submitted data and send templated notification emails to both the submitter and the receiver. Strongly consider installing FreeForm with FreeForm Spam to help reduce spam submissions.

Image Sizer (Free)

Perhaps one of the most popular ExpressionEngine plugins, Image Sizer allows you to dynamically resize and cache images on-the-fly as they are requested. This turns out to be a very important tool in improving the experience your clients have with their site.

This plugin ensures images fit your design regardless of the original images uploaded to the CMS by the client. While it might be a big deal for those of us that do this for a living, dealing with image dimensions, aspect ratios and resizing is a big hassle for most people. Installing this plugin will make your clients’ lives easier and give them a lot more confidence to go in and edit their site.

CP Analytics (Free)

As its name suggests, the CP Analytics plugin presents the website’s Google Analytics data on the ExpressionEngine CMS dashboard. This allows our clients to quickly see how their site is reaching their customers and constituents.

NSM .htaccess Generator ($14.95)

This helpful ExpressionEngine plugin, also from Leevi Graham, removes the “index.php” from ExpressionEngine CMS page URLs to create more user-friendly page URLs. This plugin is more an aesthetic preference than a necessity.

Securing ExpressionEngine

ExpressionEngine, out-of-the-box, is quite secure. However, there are several additional steps you can take to further harden ExpressionEngine website security.

Secure your server

If you are managing your own web server, you can require key-based login and disable password-based login. This is perhaps the most beneficial security precaution you can take.

Secure your database

If your MySQL server is running on the same machine as your web server, only allow connections from localhost. This prevents potential remote attempts to hack your database.

Rename the system directory

When you install ExpressionEngine, you have the opportunity to rename your ExpressionEngine system directory. Using a different name from the default value will provide a little bit of additional security through obfuscation.

Move your system directory above the web document root

Should your web server configuration become corrupted or malformed, PHP files beneath your document root could potentially be served as plain text. Moving your ExpressionEngine system directory above your document root ensures sensitive information is not inadvertently disclosed.

Process form data in Secure Mode

Processing form data in secure mode deters automated spam submission attacks. It does add one additional database query, though.

Disable “Allow Dictionary Words as Passwords”

This prevents users from using plain-text dictionary words as account passwords. Inconvenient, maybe. Secure, yes.

Consider Using CAPTCHAs

ExpressionEngine can generate and require CAPTCHAs for all form submissions. This will help prevent spam. You can enable and configure CAPTCHAs in “Admin > System Preferences > Captcha Prefences”.

Additional security preferences

You can read more about ExpressionEngine’s numerous security preferences in the online User Guide.

Optimize ExpressionEngine for Performance

ExpressionEngine will perform admirably by default. However, should your website be Fireballed, there are a few additional tweaks you can make to improve ExpressionEngine’s performance.

Query caching

When Query Caching is enabled, ExpressionEngine will log database queries to a text file. When the same query is performed, and if a related cache file exists, the cache will be used instead of calling the database. You can enable Query Caching at “Admin > System Administration > Database Settings”.

Note: It was brought to my attention in the comments that Query Caching is disabled by default and discouraged by EllisLab; native MySQL caching is much faster than using PHP for query caching. But this feature is available if needed.

Fragment caching

Expression templates support fragment caching. Simply add the “cache” and “refresh” attributes to any ExpressionEngine template tag. The “refresh” attribute value is an integer (measured in minutes), and the content of the given tag will be cached for the specified length of time. Fragment caching is preferable when you need to cache parts of a page that contains other dynamic data that may change with each request.

{exp:channel:entries channel="news" limit="10" cache="yes" refresh="10"} This content will be cached for 10 minutes {/exp:channel:entries} 

Template caching

If you prefer a more heavy-handed approach, you can cache entire pages. You can enable Template Caching and specify the refresh time period in the Templates page’s preferences panel. It doesn’t make sense to use both Fragment Caching and Template Caching together for the same page; choose one or the other but not both.

Disable unnecessary query data

When you output channel data using the {exp:channel:entries} tag, ExpressionEngine will query for a lot of information by default; some or most of the queried data may be unnecessary. You can disable certain query data to improve the performance of this tag. The items you can disable are:

  • categories
  • category_fields
  • custom_fields
  • member_data
  • pagination

To disable any of the above items, add a disable attribute to your Channel Entries tag and separate each item name with a “|” pipe.

{exp:channel:entries disable="categories|member_data|pagination" ... } 

Perform Front-End Optimizations

While not specific to EE, it is important to optimize your template code so that the site can perform its best. Generally this means following guildlines like YSlow or Google PageSpeed and testing either in Firebug or with something like GTMetrix.

A trick for making this process easier is to automate the minification and compilation of all of your css and js. We really enjoy having this functionality in HiFi. A beta EE plugin for this is Minify.ee by Leevi Graham. His other work is great so we expect this to be as well.

Prepare ExpressionEngine for Clients

By this point in the project, we have installed ExpressionEngine, purchased and installed plugins, hardened security, and optimized the CMS. The project is nearly complete and ready to deliver to the client. Before we do, though, we need to do some house-cleaning.

Create a “Clients” member group

First, we create a new Member Group specifically for the client. This allows us to expose only certain elements of the ExpressionEngine CMS to our clients.

ExpressionEngine Member Groups

Create a new Member Group called “Clients” at “Members > Member Groups”. Then, still on the “Members > Member Groups” screen, click “Edit Group” for the “Clients” member group. The most important settings we use for simplifying client access to the EE CMS are:

  • Control Panel Area Access
    • Can access PUBLISH page (YES)
    • Can access EDIT page (YES)
    • Can access TEMPLATES page (NO)
    • Can access COMMUNICATE page (YES)
    • Can access MODULES page (YES) †
    • Can access ADMIN page (NO) ††

(†) Although the client can access this panel, it will be hidden from view
(††) You may want to enable this depending on your client’s needs

There are many other access settings you can configure based on your client’s needs. If you will have many client users of various roles (ie. editor, department-specfic, etc.) it may also be necessary for you to edit the “Channel Assignment” settings for each client user to only give client users access to certain ExpressionEngine channels.

Simplify page editors

If left with default settings, ExpressionEngine channel page editors will have a lot of tabs and a lot of settings — some of which may be unnecessary. We recomend you make the UI as simple as possible with only the controls that clients need to manage their site.

ExpressionEngine Page Editors

On the “Admin > Channel Administration > Channels” screen, for each channel, click “Edit Preferences”. The most important settings we use for simplifying channel editors for clients are:

  • Administrative Preferences
    • Default Status
    • Default category
    • Select “Allow Comments” button in Publish page by default?
  • Channel Posting Preferences
    • Automatically turn URLs and email addresses into links?
  • Comment Posting Preferences
    • Allow comments in this channel?
    • Enable Captcha for Comment Posting?
    • Moderate Comments?
  • Layout Customization in Publish Page †

(†) Uncheck the items that are not needed for the client to edit content in the given channel.

On each Channel’s New Entry form, we also click “Show Sidebar” and hide unncessary tabs and fields.

Customizing each user’s Control Panel

And last, we customize each user’s Control Panel. To do this, we log into the Control Panel as each user and perform the following changes:

  • Add a new “Pages” tab that links to the Structure Module page
  • Add a new “Forms” tab that links to the FreeForm Module page

You can add additional tabs if you need to provide easy access to other Modules. Because of the changes performed in “Create a clients member group” above, the client user account should not see the “Templates” and “Admin” tabs. Our goal is to provide a simple user interface that only provides the tools required by the client — nothing more.

Moving to the production server

After the client approves the website, it is time to move the website to the production server. After you migrate your database (if necessary), you need to move over the ExpressionEngine CMS files. When you do, ensure file and folder permissions are still correct. You will also need to edit several path settings in the ExpressionEngine control panel.

Log into the ExpressionEngine Control Panel on the new server. The Control Panel styling and images will likely be missing.

General Configuration

ExpressionEngine General Preferences

Navigate to the “Admin > General Configuration” screen and edit the following fields:

  • URL to the root directory of your site
  • URL to your Control Panel index page
  • URL to your “themes” folder

Captcha Configuration

ExpressionEngine CAPTCHA Preferences

If the project uses CAPTCHAs, navigate to the “Admin > Security and Privacy > Captcha Preferences” screen and edit the following fields:

  • Server Path to Captcha Folder
  • Full URL to Captcha Folder

File Upload Preferences

ExpressionEngine File Upload Preferences

If the project accepts file uploads, navigate to the “Admin > Content Administration > File Upload Preferences” screen and edit the following fields for each File Upload Destination.

  • Server Path to Upload Directory
  • URL of Upload Directory

Template Preferences

ExpressionEngine Template Preferences

If the project saves template files to the filesystem, navigate to the “Design > Templates > Global Preferences” screen and edit the following fields:

  • Basepath to Template File Directory

Provide clients with a “How-To” guide

When you hand-off an ExpressionEngine website to a client, you may have included one-on-one training in your contract. If not, it will be helpful to provide the client with the resources to learn and use ExpressionEngine to edit his website. A great resource for clients is the HeadSpace Client Guide (PDF) for ExpressionEngine 2. This guide provides an easy-to-read overview of how to use ExpressionEngine to edit website content.


Hopefully this guide has been a helpful look into the process that we go through when we set up an ExpressionEngine site. By taking our time and ensuring that we configure and install everything necessary, we’re able to deliver a high performing site that our clients are able to manage.


maham khan's avatar
maham khan
thanks for providing the information I was looking for , and I think you should keep updating us with such useful information !!
walkin bath tub Washington's avatar
walkin bath tub Washington
This web site truly has all of the information and facts I
needed about this subject and didn't know who to ask.
Christian's avatar
After some months of self teaching expression engine i came to this post and i must say this is just excellent.

Jonathan Day's avatar
Jonathan Day
Thanks for the detailed walk-through, this is very helpful. Could you give an indication of how much time this process takes, both for an EE-experienced developer, and for someone who has worked with Wordpress or other CMS frameworks before but not EE?

duncan gatawa's avatar
duncan gatawa
Hadnt heard of expression engines.but the way you describe it,it well worth taking a look.thanks for the tips
Kyle Racki's avatar
Kyle Racki
Hi there. Just letting you know that I've provided a free, re-brandable update to the ExpressionEngine Client Guide, now updated to EE2.

Feel free to download and share - all I ask for is a link back to the site if you can. Enjoy!

Ted Avery's avatar
Ted Avery
Great write-up! I came across mostly the same plug-ins on my setup.

Just wondering, how are you integrating the Image Resizer plugin with WYGWAM? Perhaps I'm misunderstanding something totally input, but I'd appreciate your input.
Seb's avatar
@Josh. I read too many posts while researching the best solution and have nothing concrete to show.

But in another post I wrote over on the forums there's an indirect confirmation by Eric Reagan. Happily, though, it's no longer an issue if you're using a masked cp.
Josh Lockhart's avatar
Josh Lockhart NMC team member
@Seb Can you post a link to your reference?
Seb's avatar
Thanks, I enjoyed this.

But I've got an issue with the highly desirable method of moving the system folder above the root. What happens when you have to update EE to a new build or version?

I've read that the installer can't cope with this scenario; and that you're obliged to move the system folder back down, switch your paths accordingly, carry out your installation and then move it back up again.
Edwin's avatar
Excellent article. Very helpful.
Mike's avatar
Thanks for this, I'll probably reference it a lot in the future!
Ben Seigel's avatar
Ben Seigel
Under 'File Upload Preferences', we use relative paths for images, never absolute.


Euan's avatar
Thank you for the write up, very interesting to see how you set up an install and what add-ons you install from the start.
Travis Schmeisser's avatar
Travis Schmeisser
Great writeup! Glad Structure is working well for you. Shoot us an email if you ever have any feature ideas/requests. Thanks!
Derek Hogue's avatar
Derek Hogue
Thanks for this Josh, an excellent and comprehensive walkthrough for newcomers to EE. I should add that an additional level of spam protection for Freeform is my Spam-Freeform extension, free for both EE1 and EE2.
Natalia Ventre's avatar
Natalia Ventre
Very good guide. There are many add-ons to make the client's life easier, besides the ones you mentioned, I'll add Blueprints and Low variables (for contact info and configure Google Analytics).

And as a developer, deploy helper is great to re-use the installation, because as you said on "Move to the production server" there are several paths to change and I'm always afraid to forget something.
Josh Lockhart's avatar
Josh Lockhart NMC team member
@Andwry Thanks for catching that. Updated.
Andwry's avatar
Good article, but one note - LG .htaccess Generator for EE2 is commercial now.
Josh Lockhart's avatar
Josh Lockhart NMC team member
Thanks for the kind words! @Michael I appreciate the link. I've updated the Query Caching section accordingly.
Michael Hessling's avatar
Michael Hessling
Solid. My only caveat might be the Query caching. EllisLab recommends you don't use it[1], and it some cases, it will actually make your site slower (e.g., on MediaTemple).

1. http://expressionengine.com/forums/viewthread/170479/#812281
Cem Meric's avatar
Cem Meric
Great write up Josh
John Macpherson's avatar
John Macpherson
Awesome guide, thanks!

Leave a comment