Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

December 10 2013


Statamic 101

Statamic is a modern PHP CMS which really makes an effort to be easy and intuitive to use. From its flat-file design to its use of technologies, like markdown and Yaml, you can accomplish an outstanding amount of work without writing any code at all.

In this article we will take a look at the process from installation to setting up a basic portfolio.

Having a flat-file design, setup is as simple as extracting the zip file you’ll download from their site. There is no database involved, all the content and settings are stored locally in a host of different files, this also means you have automatic backups and versioning on all of your content, if you use something like GIT.

With the contents extracted, let's take a look at Statamic’s structure.

The File Structure

There are more or less five different folders you will most likely be interacting with, and they are:

  • _config is where all your settings are held
  • _content is where you will put your Markdown files
  • _add-ons is for Statamic add-ons
  • _themes is where you build your theme
  • assets is where you can stick resources for your site

Besides these, you have the following four folders that you probably won't touch directly:

  • _app – Statamic’s own source code
  • _cache – Where Statamic caches all your content
  • _logs – Where Statamic will store your logs
  • admin – The Statamic admin panel

But the first step in every Statamic site is to configure its options.


All the configuration files are inside the _config folder like we just saw, the main file you should take a look at is the settings.yaml.

If you are new to Yaml, then all you really need to know, is that it's a data format similar to JSON except that it's meant to be a more human-readable format. It accomplishes this by not requiring any separating characters like semi-colons or quotation marks, instead it get's its structure from placement and indentation.

The settings.yaml file is really well documented so you shouldn't have a problem filling it out, some of the options you will probably want to look at are the following:

_license_key: Enter your License Key
_site_name: My Portfolio
_site_url: http://localhost:7000
_theme: portfolio
   - language
_log_enabled: true
_cookies.secret_key: Some Random Key

Most of these are pretty straight forward, like setting the license key, your site's name and URL. The theme option sets which theme folder to load. We will get into this in a moment, but a theme is essentially the place where you specify how the different pages on your site will work. We will be creating our own theme so you can name it whatever you want, I chose ‘portfolio’.

The next option is an array called taxonomy, if you have ever used something like WordPress, then you should know what this is for, basically it allows you to add a setting or 'type' to each post, which you can then use these taxonomies to filter your content and create custom pages for these groupings.

I am just adding one taxonomy; the language taxonomy, because in our example portfolio we are going to specify each work’s programming languages. You don’t need to create a taxonomy for each custom property, we are going to want other things in our portfolio, like links and descriptions. A taxonomy is for fields that multiple entries have in common, and for fields that you may want to create a custom page for.

The log_enabled setting turns on logging, so you can view problems which come up from the admin panel, they will be stored in the _logs folder we saw earlier. Finally the last option I mentioned is the secret key used to encrypt the cookie.

This file can now be saved out, but before we move onto content, let's take a moment to setup the portfolio template so we can see what we are doing.

Theme Basics

The template is a specific view for a single page.

Like most modern frameworks, when you load a page, you can build it up from multiple reusable components. A page in Statamic is made up of a layout a template and a content file. Both the layout files and templates can optionally also be made of even more pieces called partials.

The layout is the outer shell in which your template will be placed; this is usually used to hold the boilerplate HTML code like the head section, and as-well as the basic body that all the pages using this layout will need, like adding common libraries at the bottom of your file.

The template is a specific view for a single page. Like you can have a home page template, a contact page template, etc.. You don't need to create on per page, but I would say one per type of page.

In these templates you have the ability to use variables stored in the actual content files, so say you need a page which displays an index of books you are reading, and then another page to display a list of shows you are watching; instead of replicating most of the code for each one, you can create one template for displaying a list of objects, and then pull in the specifics of which list to retrieve from the content file itself.

The content file – like its name suggests – is the actual resource being displayed, this can range from things like an actual unique web page, to a single blog entry. We will get to these in more details in a moment.

Now instead of manually creating all these different components, Statamic provides a sort of starter template, giving you a basic structure to get started. You can download the theme folder from here.

Just place the entire folder into the _themes directory, and rename it to portfolio (as that's the theme name we declared in the settings file). You also need to rename the kindling.js file from the js folder and the kindling.css file from the css directory, to portfolio.js and portfolio.css respectively, as their is a special tag to pull these in automatically.

That's all the setup we need now, but to get a better idea of what I was talking about regarding the layout/template, let's take a look at those files. To begin with open up the file named default.html from the layouts folder, this corresponds to the default layout as you may have guessed.

<!DOCTYPE html>
<html lang="en">
        <meta charset="utf-8" />
        <title>{{ _site_name }}</title>
        <link rel="stylesheet" href="{{ theme:css }}">

        {{ layout_content }}

        <script src=""></script>
        <script src="{{ theme:js }}"></script>


Like I mentioned earlier, the layout is a good place to put code that is required on multiple pages (or templates rather), which is why the default layout in this file just contains the basic outline of an HTML file. Now we haven't really talked about it yet, but Statamic comes with its own templating engine, which is fairly easy to pick up, you basically just place a tag where you want something to be inserted similar to Handlebars if you are familiar.

This layout contains a couple of tags which I thought I would go through, the first of which is _site_name. This tag actually refers to the property we set up inside of the settings.yaml file. You will find this convention all throughout Statamic, you can set yaml options either globally like this, or even on a per-file basis, you can then get these options just by placing a tag with their names into your templates.

Helpers in Statamic are more like independent modules.

The next tag, which actually comes up twice is the theme tag. Helpers in Statamic are more like independent modules, so they can have multiple different functions attached to the same name; you access the individual functions with a colon and then the name of the command you want.

The theme tag is all about loading in resources specific to this theme, it can be used to pull in things like scripts and stylesheets, but also things like images and partials. It's a helper function that basically allows you to just provide the name of the resource you want and it will fill in the path to the current templates directory. So for instance if you were to write:

{{ theme:js src="underscore.js" }}

It would replace that with a link to a file named underscore.js inside of the current theme’s js folder. By default if no src parameter is set for the js or css command, it will assume you are referring to a js or css file with the name of the current theme, which is why we renamed those files to match; it's just a matter of convenience so we don't need to specify them and it cleans up the source a little bit.

The next tag that comes up is {{ layout_content }}; this is similar to yield in other templating engines, and it basically signifies where the inner template should be inserted.

The last thing I want to do in this file is remove the link to jQuery, just because I won't be using it (if you will then you can of-course leave it).

Next let's move onto the default template file (templates/default.html), it should be blank. For illustrations sake, let's just add a tag called {{content}} which just inserts the contents of the current page being loaded.

So to recap when you goto a page it will first load the layout file, and then wherever the {{layout_content}} tag is placed this template will get inserted. This template will then just output whatever the current page has inside.

With that done, save out these files and let's move onto content.

The Content

Content in Statamic is specified in markdown files by default, and the default file which is loaded is called What I mean by this is that the same way standard web server will load index.html if no file was specified, Statamic will load

It's also worth noting that routes, or URL links in your site will be defined by the _content directory. So for example if you create a folder named 'demo' inside of the _content directory, and in it place a file named '' this will correspond to the URL /demo/link; and if you place a file inside, it will be loaded if you navigate to /demo/ since it is the default file name.

Statamic comes with some demo content, but you can just delete everything inside the _content directory for this example (or move it aside for now).

Let's start with a basic home page, so at the root of the _content directory, create a file named with the following:

title: Home

# Welcome to the {{title}} Page

All content files are basically split into two sections, the Yaml front-matter and the contents. The top part (between the dashed lines) is where you can put standard Yaml specific to this file, and is a good way for setting options to adjust your template files. The second part is the markdown area, where you put the contents of the actual page. You can use standard markdown as-well as Statamic helper tags.

This page will load with the default layout and template files we just setup, but if you want it to use a different one, you can specify these as options in the Yaml section at the top using _layout and _template respectively.

If you create a server at the root of your Statamic directory:

php -S localhost:7000

and then navigate to http://localhost:7000 in your browser you should see the H1 tag with our welcome message.

This is all you need to know to create pages in Statamic, and if you are building a fairly static site, this would be enough. But in a lot of sites we need to be able to add dynamic data, which can take the form of blog posts, shop items, or in our case portfolio works.


If you recall there is no database in Statamic, so these kinds of entries are stored in markdown files just like the page we just built, although a couple of things were done to subtly introduce multiple features to optimize things and to make it work in the admin.

First off you can name the files with a special date format so they can be sorted and filtered by date. You do this by pre-pending the title with a year-month-day pattern, so say you want to create a post named 'foobar' you would name it something like:

Inside you would put all the posts settings inside the front-matter section for use in the template, and then any content underneath; just like in a page.

Now this is pretty cool, but it's the equivalent of manually entering posts into a database of a traditional system; there is another option.

Statamic comes bundled with a really nice admin, which can do all this for you, but in order to get it setup we need to tell it which fields this type of entry is supposed to have. This is done in a file appropriately named fields.yaml.

So for our example let's create a folder inside the _content directory named works, and inside the works folder let's create a file named fields.yaml. Inside the fields.yaml file we need to specify which properties our 'entries' will contain and the individual types for each of these settings.

You can either specify your fieldset (the list of fields) in the _config/fieldsets/ directory and pull in a definition, or you can just enter the definition here (or you can do both to extend an existing definition). For our simple example I am just going to put the definition here since we won't be reusing it anywhere:

type: date
   type: tags
   display: Programming Language
   required: true

    type: text
    display: Description
    required: false

    type: text
    display: Link
    required: true

    type: hidden

The first property just tells Statamic that we want these entry files to have a date property and to be named appropriately. Next we open up a YAML object named fields containing all our work entry's properties.

The first is the language field, which if you remember is the taxonomy we created in the settings.yaml. Inside each property we need to specify its type (or it defaults to a text box) its display text (which will default to the properties name) and whether it is required. There are other options you can set as-well like instructions or the default value, which you can view more information about here, besides for these settings different field types can have their own custom options.

For the language input I set it to use the tag type, which basically allows you to set multiple tags for this option, it's just a different type of input for entering its value in the admin. You can view all the different fieldtypes here or from the official cheat sheet under 'Fieldtypes'.

The description and link are pretty much the same, they will both be text boxes except one will be required and one won't be. Besides the fields you specify all entries will come with a title and content field. We don't really want a content field in our works they will be more like links, so I just set it to hidden.

The last step before we go to the admin, is to create a file inside the works directory. This isn't really required but the admin will attempt to get the title of this entry type from here so it's a good idea to just place it. So create a file inside the works folder with just the title set to 'Works':

title: Works

The Admin

To get into the admin we need to first create a user; again this is a simple yaml file inside of the config folder. The name of the file is the username you will use to login, and inside you configure the user's details and password.

So let's create a new user with a username of editor, again we do this by creating a file called 'editor.yaml' inside of the _config/users/ folder. Insert the following data (except with your info):

first_name: Gabriel
last_name: Manricks
roles: [admin]
password: password

The Editor of this Portfolio

Most of these columns are pretty straight forward and I don't think they require any explanation. The only field worth mentioning is the roles setting. Currently admin is the only option available, but in the future this will be where you would be able to adjust who can edit what.

It's also worth mentioning that the password will not stay in plain-text. After the first login, Statamic will hash the password along with a salt and include those here instead.

Everything after the dashed lines will just be stored as the content for this user, and can be used as a sort of bio for them.

Now save this file, and if your web server is still running, navigate to /admin in your browser. This will open up the login console where you can enter these properties. Like I mentioned the first time you login you will need to do this twice, once to hash the password, and the second time to actually login.

Admin Login The Statamic Login

Once in you will see a list of our pages, included is our home page as-well as the 'Works' entry type. Let's take a look at what our fields declaration did for us; click on the Create link inside of the 'Works' bar.

Pages Admin

You should see a nice form which includes all the fields we specified along with the tite, for this demos sake, just add a few posts.

Demo Post

With some posts stored, we have completed round one; you now know how to create pages, themes, users, and entries, it's a great first step. But there is alot more Statamic has to offer.

The Templating Engine

Having some posts created is nice, but what would be better is if we could actually display them on a page. For this we will need to edit the default template.

This will be our first real interaction with the included templating engine, but not to worry, Statamic's intuitive design makes it almost 'obvious' to pick up.

To view a full list of the available tags you can take a look at the official doc page on the matter. But all we really need in our example is the entries tag, which is used to pull in entries from a specific folder in the _content directory. There are a lot of optional properties, allowing you to filter by date, or conditions like taxonomies or even standard properties. We are going to keep it simple and just list the properties by date (which is the default).

Here is the complete new default template (templates/default.html):


 {{ entries:listing folder="works" }}
         <td class="lang"><p>{{ language }}</p></td>
         <td class="work">
             <a href="{{ link }}">
                 <span class="title">{{ title }} - </span>
                 <span class="desc">{{ description }}</span>
 {{ /entries:listing }}

In this code we are creating a table and just looping through all posts in the 'works' directory. These kind of block tags, where you place more HTML inside, basically assign new placeholders. Besides for providing access to things like all the post's attributes, you also get special helper variables which can tell you things like the current index, or whether this is the first or last post. We won't be using any of those variables, all we need is to display the title / language / description and link. However if you load up the page in your browser, you will probably realize that instead of showing the language it just says "Array".

This is because we set this property to be of type tag, which means it could hold more than one language, so even though you may have only put one language, it is still being stored in an array. Luckily besides for these tag helpers, Statamic comes with modifiers.


To finish off this guide, let's take a look at a few modifiers which will allow us to make this page even better.

The first and biggest problem is making the language show up. If you take a look at the following cheat sheet, all the way at the bottom left, you will see a section named List Shortcuts. While not technically being modifiers, Statamic allows you to append these words to the end of a list variable, and it will instead return a string representation. The one I want to use in this situation is the standard _list helper. What this will do is separate multiple values in the array with a comma and space, and is what we would want in our situation.

To try it out, replace the {{ language }} tag to {{ language_list }}. Refreshing your browser it should be displaying the languages correctly now.

Next let's add a modifier to the title to make it all uppercase. If you have ever used something like the smarty templating engine, then it works the same way. You add a pipe to the end of the variable name and then add a modifier. In our example you just need to replace the call to {{ title }} with {{ title|upper }} and these are chainable so you can keep adding pipes indefinitely.

Now let's just add some CSS to style everything up (remember this goes in the css/portfolio.css file:

body { background: #FAFAF5; }

h1 {
 font: 800 64px 'Raleway', sans-serif;
 margin-bottom: 28px;

table { font: 15px 'Coustard', serif; }

td { padding: 10px 10px 0 10px; }
p { margin-bottom: 15px; }

.lang p {
 background: #CA9F53;
 color: #FFF;
 padding: 3px 5px;
 text-align: right;

.work { text-align:left; }
.work a{
 border-bottom: 1px solid #000;
 text-decoration: none;

.title {
 font-weight: 600;
 color: #000;

.desc { color: #666; }

And these two fonts are from Google Fonts, so you will need to add the following link at the top of your default layout file:

<!DOCTYPE html>
<html lang="en">
 <meta charset="utf-8" />
 <title>{{ _site_name }}</title>
 <link href='|Raleway:800' rel='stylesheet' type='text/css'>
 <link rel="stylesheet" href="{{ theme:css }}">

 {{ layout_content }}

 <script src="{{ theme:js }}"></script>


If everything worked out you should see the following page (except with the works you added)

The Demo


Where I think this will thrive is as a blogging platform or CMS.

In this article we have went through the entire process from installing the framework, to setting everything up, creating a new entry type, and building a custom theme. It's a lot to do, and it's only possible because of how easy Statamic makes things.

We have seen alot of functionality already and we haven't even touched on creating your own modules, and extending Statamic with PHP, but I think the most amazing thing is we haven’t even written a single line of PHP in this entire article! And that is something to brag about.

So I think the main question people might have is, should I use it, or what should this replace in my current repertoire? It's important to gauge what Statamic is for. If you are building a new Startup and need the full flexibility of a full fledged framework, I am sure you would be able to get it running in Statamic, but it would be alot of custom code, which may defeat the purpose. Where I think this will thrive is as a blogging platform or CMS.

Coming from a background in WordPress, this feels like a direct predecessor, in that it follows a-lot of the same conventions in theory, but they are all implemented in a much smarter way, in that comparing the amount of code required in each becomes a joke. Moving forward, Statamic has an incredible API for building custom tags, hooks, new fieldtypes and more, and you can imagine Statamic makes it as lean and simple to do as you might have come to expect.

I hope you enjoyed this article, if you have any questions feel free to ask me below, on twitter @gabrielmanricks or on the Nettuts+ IRC channel on freenode (#nettuts).

June 27 2011


Create a Facebook Recent Activity Drupal Module

Advertise here

Enhancing Drupal’s built-in functionality with new modules is one of the features that attracted a lot of developers to the platform and made it extremely popular. This tutorial will demonstrate how to create a Drupal module, using techniques recommended by Drupal gurus.

Before getting our hands dirty, let’s take a look at what are we going to learn.


In order to fully understand the information presented in this tutorial, you need to have the following knowledge:

  • basic Drupal administration including installing Drupal, enabling a module, adding some content
  • basic PHP knowledge

Drupal Hooks

The Drupal codebase is modular and consists of two parts:

  • the core modules (the core)
  • the contributed modules (the modules)

The core provides all the basic Drupal functionalities, and the modules add more features to the base installation. Interaction between modules and the core is done via “hooks”.

According to Drupal’s documentation:

“A hook is a PHP function that is named foo_bar(), where foo is the name of the module (whose filename is thus foo.module) and bar is the name of the hook.”

So, the hook is a function with a special name that is called by the Drupal system in order to allow modules to include their functionality to the core. The file containing these functions also has a special name which allows the core to find all the installed modules.

The Drupal API provides the developer with a large number of hooks with which to alter almost the whole functionality of the core. For a Drupal developer, the sky is the limit for creating a site based on this powerful CMS.

Separating the basic functionality from the auxiliary features enables an increased flexibility on performing administrative tasks such as upgrading Drupal to a newer version. Since the core is somehow independent on modules, this operation can be done just by overriding the core.

What We’re Building Today

We need a realistic goal for implementing our module, and I think Facebook integration is the perfect idea. We will allow the user to “like” our articles by adding a Facebook ‘Like’ button to each of them. The second task of our module will be to show, in the sidebar, which articles were liked by the users.

Obtaining the Data

Since the main focus of this article is on how to implement a Drupal module, we will use the simplest method to retrieve the data from Facebook: Social Plugins. Social Plugins allow users to add Facebook elements to your site with only a single line of code, which can be taken out with copy/paste from the Facebook site.

Our final product will have an output which should look like so:

Final Product

Step 1: Setup

Drupal searches for contributed modules in the sites/all/modules folder of your Drupal installation. In case an administrator decides to have multiple sites driven by one Drupal installation, the path to the contributed module will look like sites/subdomain/modules.

First, let’s choose a name for our module. Since its task will be to add Facebook functionality to our site, I assume “facebook” will be a proper name for it. We can start preparing the required directory structure for developing our module.

Inside sites/all create a subfolder, named modules. We will store our contributed modules in a subfolder named custom. The Facebook module will reside in the facebook subdirectory of the custom directory. The final structure will look like so:

Final Product

Step 2: Inform Drupal about our Module

Drupal presents the user with a list of core and contributed modules based on the content of sites/all/modules. For each module present, Drupal searches for a file named This file should contain information about the specific module and Drupal displays this information to the user.

Let’s create the info file for our module. Create a file, named in the sites/all/modules/custom/facebook folder, and add the following code to it:

  ; the module's user friendly name, will be displayed in the modules list
  name = Facebook Recent Activity
  ; the module's description, will be displayed in the second column in the modules list
  description = Retrieves and displays in a block the recent activity data from Facebook.
  ; the module's package, will be the name of the module's group on the modules list page
  package = Nettuts+ Drupal Module Tutorial
  ; the Drupal core package
  core = 7.x
  ; the files array indicating which files are part of the module
  files[] = facebook.module

The code above reveals the required information to be placed in an info file. Notice that we’ve referenced the facebook.module in the files array. This file will contain our module’s code. For the moment, go ahead and create an empty file in our folder.

The .info file is a standard .ini file; therefore, the lines starting with “;” are comments.


Now, let’s check what we’ve done so far. Visit your website and select Modules from the upper main menu. The modules list should be displayed, and at the bottom of it, you will find a new module group, named Nettuts+ Tutorial Module containing our module. Check out how the information you’ve placed in the info file is displayed here.

Final Product

Step 3: Add the Like Button

We need to add the code provided by Facebook to the Drupal code that processes the node. This can be done by implementing hook_node_view.

As we will find in a moment, implementing hook_node_view requires using the theme function.

A theme function is a Drupal API function that is used to allow desginers to theme the modules as desired. The fact that we will use the function also means that we will have to implement hook_theme too.

Retrieving the Code from Facebook

The Facebook code that displays the ‘Like’ button on the pages can be obtained here. You can customize the look of the button using the controls on the page. Pressing the Get Code button displays the required XFBML code.

Final Product

Implement hook_node_view

The hook_node_view returns the renderable view of the nodes (articles or pages for instance). Using this hook, we can add custom code to the one generated by Drupal by default. The implementation of this hook looks like so:

   * Implements hook_node_view().
   * Returns the renderable view of our nodes (pages or articles).
   * We want to moddify the code so that we add the like button
   * to our pages.
  function facebook_node_view($node, $view_mode, $langcode)
    $node->content['facebook'] = array(
      '#markup' => theme('facebook_add_like_button'),

The name of the function is facebook_node_view, so you can deduce that it is composed from the name of our module and the name of the hook.

The parameters are:

  • $node — contains the node data that will be rendered lately
  • $view_mode — specifies how the node is displayed (can be full mode, teaser etc.)
  • $langcode — to control the language code for rendering

We modify only the $node parameter and the result will be that our ‘Like’ button will appear also when a node teaser is displayed. I leave it as an exercise for you to modify the code to display the Like button only on full pages.

The code adds a new key to the $node->content array, which says that the markup for the facebook module will be rendered by the facebook_add_like_button function.

Implement hook_theme

This hook should be implemented to register the implementation of the theme function.

   * Implements hook_theme().
   * Just to let Drupal know about our theme function.
  function facebook_theme()
    return array(
      'facebook_add_like_button' => array('variables' => NULL),

The code returns an array containing the name and parameteres of the function. In our case, we don’t require any parameters, so the array of variables is set to NULL.

Implement our theme Function

Finally, we’ve reached the moment when we can add the code taken from Facebook to our module. This can be done like so:

   * Function to add the desired code to our page.
  function theme_facebook_add_like_button()
    $output = '&lt;div id="fb-root"&gt;&lt;/div&gt;&lt;script src=""&gt;&lt;/script&gt;&lt;fb:like href="" send="true" width="450" show_faces="true" font=""&gt;&lt;/fb:like&gt;';

    return $output;

Note that the function’s name is composed from the name registered by theme hook prefixed with theme_. The function returns a string containing the code taken from Facebook.


We can now check to see if everything is okay up to this point. You can activate the module by clicking on Modules from the upper menu, scrolling down to the Facebook module and activating the enable check box in front of our module.

Click on Save configuration button to enable the module. If you do not have any articles added to your site, add some now and check out the spiffy buttons that have been added.

Your posts should look like below:

Final Product

Step 4: Create the Sidebar Block

Creating the sidebar block consists of two actions:

First, we have to let Drupal know about the existence of a new block and make it appear in the list of available blocks. Second, we have to write the code that displays information in the block.

This assumes implementation of the hooks: the hook_block_info, which will list our block in the block list, and hook_block_view, which contains the necessary code to display the Facebook recent activity inside the block.

Implementing hook_block_info

   * Implements hook_block_info().
   * Using this hook we declare to Drupal that our module
   * provides one block identified as facebook
  function facebook_block_info()
    $blocks['facebook'] = array(
      'info' => t('Facebook Recent Activity'),
    // leave the other properties of the block default

    return $blocks;

The block_info hook tweaks the $blocks array by adding a new key, named info to it, which contains the text that will be available on the blocks page near our Facebook module.

Implementing hook_block_view

The first thing to do is take the Facebook code, available here. We need to configure the default options: set the width to 170 and the header to false (uncheck the Show header checkbox).

We need a 170px wide block, since this is the standard Drupal block width and we will set up our own text for the header — therefore, we don’t need Facebook’s title.

Let’s check the code for hook_block_view:

   * Implements hook_block_view().
   * Returns the renderable view of our block. It takes
   * the configured values of facebook recent activity
   * social plugin
  function facebook_block_view($delta = '')
    switch($delta) {
    case 'facebook' :
      $block['subject'] = t('Facebook recent activity');
      $block['content'] = '&lt;script src="">&lt;/script&gt;&lt;fb:activity site="" width="170" height="500" header="false" font="" border_color="#fff" recommendations="false"&gt;&lt;/fb:activity&gt;';

    return $block;

The block view hook receives a single parameter, which is an indication of which block is rendered. We check to see if the block belongs to our module and, if yes, we add two new items to the $block array:

  • a subject string, which will be the title of the block
  • a content string, which, in our case, is taken from Facebook.

We’re almost ready. Enable the module, then navigate to Structure in the main menu, then choose Blocks and scroll down to the disabled list of blocks, and set our Facebook recent activity block to be displayed in the second sidebar (which will appear on right on the default theme).

Next, press the like button for some of the articles previously created. These will appear listed in the sidebar in our freshly created block.

That’s it! We’re done. The result should look like so:

Final Product

Wrapping Up

I hope this tutorial convinced you that creating a Drupal module isn’t really as hard as you might think. Of course, this tutorial only scratches the surface of what Drupal modules can accomplish. Nonetheless, this should be an excellent starting point!

Thank you so much for reading and let me know if you have any questions!

Sponsored post
Reposted bySchrammelhammelMrCoffeinmybetterworldkonikonikonikonikoniambassadorofdumbgroeschtlNaitliszpikkumyygittimmoejeschgeKameeel

January 10 2011


What’s New in Drupal 7

Drupal is one of the most popular content management systems (CMS) out there. To mark the new year, Drupal 7, the next major version of Drupal, is being released! In this article, I’ll walk you through some of the most exciting new features.

New Themes

The old themes have been replaced with powerful, new ones.

If you’ve worked with Drupal 6, you may have noticed the default “Garland” theme looks a bit outdated by now. Furthermore, using Garland for site administration and content editing is, frankly, not very intuitive.

Drupal 7 changes all that! The old themes have been discarded and replaced with a powerful theme trio:

  • Bartik - The attractive new default theme your users will see
  • Seven – The new administrative theme. If you’ve worked with Drupal 6, you will love this new administrative theme (more about that in a following section).
  • Stark - A blank theme that helps theme developers (aka the themers) understand Drupal’s default HTML and CSS

As always, these themes can be replaced by a theme you download and install from or by a custom theme of your own making!

Revamped Admin Interface

One of the most intrinsic functions of any CMS, be it WordPress, Joomla, or Drupal, is to provide an easy way for end-users to update content. Drupal 6 has some very good administrative themes, such as Rubik, but Drupal 7 makes creating, updating, and editing content far simpler. Take a look at the following short video to get a feel for the new administrative interface:

A video demonstration of the Drupal 7 Administrative Interface

Improved Theming Layer

Meaningful HTML is not a strong suit of Drupal 6, but Drupal 7 delivers big-time.

Another important features of any CMS is the ability to take full control over the look and feel of the site you’re building. Drupal 6 has a fantastic theming layer, but it does have a few quirks that are ironed out in Drupal 7. As a note, template files in Drupal end with the .tpl.php extension, which is often pronounced “tipple-fip” for brevity.

If you’ve worked with Drupal 6 themes, perhaps the biggest change you’ll notice is the introduction of html.tpl.php, which is used to display the basic html structure of a single Drupal page, including DOCTYPE, head, html, and body. In Drupal 6, page.tpl.php used to include these elements, but is now used specifically to display the content of a single page. This change should free themers from declaring DOCTYPES, head, etc. in multiple files, thus making maintenance and changes simpler.

Unsemantic class names have been renamed. For example, the class block-blog-0 has been renamed block-blog-recent, and block-profile-0 has become block-profile-author-information. While this may seem minor, meaningful and semantic classnames can greatly speed up theme development and make debugging CSS issues clearer.

There’s far too much to cover in one small section, from hidden regions to new PHP functions. If you’re interested in learning more about changes to the theme layer, check out the following links:

jQuery Updates

For the front-end developers out there, this is a big one. Unfortunately, Drupal 6 still ships with jQuery 1.2.6, and upgrading isn’t simple. Luckily, Drupal 7 ships with jQuery 1.4.4, which is significantly faster than jQuery 1.2.6, and provides developers with access to fantastic features such as .delegate() and $.proxy().

Drupal 7 ships with jQuery 1.4.4

In addition to updating jQuery, Drupal 7 will also ship with jQueryUI 1.8. jQueryUI is a smart addition which should help standardize many UI components, such as tabs, drag & drop events, or accordions. There are loads of Drupal modules which try to fulfill these tasks in Drupal 6. Therefore, standardizing around one UI library in Drupal 7 should make front-end development and maintenance easier.

Drupal 7 Ships with CCK

CCK is the Drupal equivalent of WordPress’ custom post types

For those unfamiliar with Drupal, CCK stands for Content Construction Kit, and it is one of the coolest features of Drupal. While CCK used to be an add-on module, it is now included with Drupal 7 by default.

Essentially, CCK allows you to quickly create new content types, such as an article, blog post, or even music album. You can easily add fields to your content type using the administrative interface. For example, you could add Album Name, Tracks, Producer and release year to a music album content type. Once the content type is created with the appropriate fields, content contributors can start entering in content while you work on the technical parts of the site! If that explanation didn’t get you excited about content types, check out this quick video:

A video demonstrating the Content Construction Kit:

RDF Support

Drupal 7 is the first major CMS to implement RDF.

Have you heard of the Semantic Web, otherwise known as the Giant Global Graph? According to Wikipedia, the semantic web is a group of methods and technologies to allow machines to understand the meaning – or ‘semantics’ – of information on the World Wide Web. In practice, the semantic web should vastly improve search engines, mashups, and data mining.

But what technology is used to implement the semantic web on our sites? That technology is called RDF. Drupal 7 is the first major CMS to implement RDF.

If you haven’t heard of RDF yet, and remain unconvinced of its usefulness, I would highly recommend you watch the following video from DrupalCon to get an idea for what RDF can do for your site: The story of RDF in Drupal 7 and what it means for the Web at large.


This article has covered many of the most exciting features of Drupal 7, but there’s even more! For those interested in Drupal module development, Fields are being overhauled and should make the creation of modules even simpler. Installation profiles have become easier to create and maintain. What are you favorite features of Drupal 7? Tell us in the comments!

Download Drupal 7.

December 09 2010


Apply the DRY Principle to Build Websites With ExpressionEngine 2

ExpressionEngine 2 is a wonderful CMS and arguably the most designer-friendly one out there, used by many well-known names like A List Apart, Andy Clarke and Veerle Pieters. Ironically, however, its default configuration is poorly suited for use in a professional web development workflow, which usually involves multiple sites, servers, and developers.

This tutorial will show you how to customize ExpressionEngine 2 so you can hit the ground running with a rock solid yet flexible starting point that can easily be deployed to multiple environments in minutes.


I’m not a programmer. However, the programming mantra don’t repeat yourself, or the DRY principle for those acronym lovers among us, has really begun to resonate within me as I get more involved both with web development and running my own business. In fact, DRY is good advice for living out your life in general. Repeating yourself costs more time up front, and potentially a lot more down the road if you have to go back and make the same change in multiple places.

Plus it’s a hindrance for personal growth because if you’re doing something you’ve already done, you’re not learning something new. What’s better is to identify those places where you do repeat yourself and come up with a system to standardize that task or piece of data.

A Little History

When I first started working with ExpressionEngine a year and a half ago, it was a one-off project and I was a novice designer. Needless to say, the DRY mentality was the furthest thing from my mind. I was happily humming along, mucking with settings as the situation dictated, not documenting anything and having a blast with custom fields and template groups, those things that make EE a designer’s dream come true. It was sort of like my first date with the software. In the end, I liked EE so much that I decided to get exclusive and “marry” it as my CMS of choice for all future projects.

After about the third or fourth site, however, I began to see flaws in our relationship (as is liable to happen when you really get familiar with something) and got frustrated doing menial, repetitive tasks related to deploying and managing EE. This was especially apparent with some ongoing projects which required twice or thrice weekly updates from development to staging to live servers. It got to the point that I was spending nearly as much time managing deployments as I was actually coding.

The Solution

Not content to lose money and slave away at boring drudgery, I sought to tidy up the mess.

What follows is the fruit of my and others’ labor, a guide to applying the DRY principle to developing and deploying sites with EE.

It walks you through how I’ve tweaked and customized ExpressionEngine 2’s flabby, nonsensical default configuration into a lean, efficient workhorse that takes nearly all the repetition out of working with EE. Specifically, these modifications will:

  • Provide a starting point with all the commonly used addons installed and settings turned on so you’re not running the installation wizard and starting from scratch every time.
  • Integrate EE with a version control system of your choice for rapid deployment to multiple web servers or developers’ workstations and easy management of code. My experience is with SVN but all the principles apply to Git as well.
  • Centralize all settings and configs to facilitate easy migration from one server to another, so launching and pushing updates is a cinch rather than a headache.

This has been a rather large endeavour and I couldn’t have done it alone. A big thanks go out to the following people, who helped me whether they knew it or not:

Step 1: Download and Installation

For your sanity’s sake get a fresh copy of the latest build of EE 2 before you do any of this. Download and install as normal, preferably on a local server, as you’ll be making lots of changes to the files. Leave out the Agile Records templates when you are prompted.

Step 2: Pouring Out the Config Soup

If you’ve ever had to migrate ExpressionEngine from one server to another, you know that this task is no easy feat; in fact, it’s a complete nightmare if you’re unprepared. A lot of this stems from the fact that ExpressionEngine stores config variables and server paths all over creation, to the point that it’s difficult to track them all down and adjust them when you move servers.

Deployment requires updating the URL and path information in literally about a dozen places. It’s clumsy, time-consuming, and error prone.”

Kenn Christ’s quote on your right is right on. Fortunately, there’s another way. Rather than editing all those variables in a dozen places in the control panel and probably forgetting some, you can consolidate them in one place—the config file. By default, ExpressionEngine stores config information that you will need to worry about in two files. These are:

  • system/expressionengine/config/config.php
  • system/expressionengine/config/database.php

Ditching database.php

As you might imagine, database.php stores the MySQL database connection information. I suppose EllisLab takes the position that it’s easier to find the DB information if it’s in it’s own aptly named file, but I’m going to argue the opposite. This is DRY, damn it! I’d rather open one file and edit my settings from one place, not two, so I did away with database.php altogether. Well, not quite, but I did take all the database settings from it and move them to config.php with a little PHP.


if ( ! defined('EXT')){
exit('Invalid file request');


require 'config.php';



You’ll never need to open database.php again.

Consolidating config.php

So now we have our database settings in config.php, plus a bunch of other stuff that you’ve probably edited in the control panel but had no idea it could hang out here as well, like template preferences, themes preferences, CP URL etc. Great, so we’re all done and we can deploy from our version control repository to any server we please with the tap-tap-tap of an SSH command.

Wrong. Here’s our problem; when EE moves from one server to another, things like the database connection settings need to change to reflect the new server environment. If we want to use EE with a version control system (and trust me, we do), then every time we deploy a working copy to a new server, we would need to download a copy of the config.php, edit the settings so they’re correct for that server, FTP it back up to the server, and make sure to tell our version control to ignore it when we issue a commit or update.

Best case scenario, we’d have a separate, non version-controlled config file for each additional server on which the site resides. For me (and I’m a one-man show) that’s:

  • iMac’s local server
  • Macbook Pro’s local server
  • staging server
  • live server

Add another couple developers if you work at an agency and you’re looking at a lot of these buggers running around. So what happens when you need to change another config variable, like the license number? Do you email yourself and other developers a copy of this file and upload it to all servers one by one? DRY, my friends, DRY. The only logical answer is a single, version controlled config.php file which can accommodate all server environments.

Nonsense, you might say, but thanks to some clever PHP it is indeed possible. As you can see, the PHP case syntax looks for an IP address and serves what I call environmental config variables based on that IP. Now the only things you need to know and change when you deploy to a new server are the IP address and the database connection information, which should be readily available to you.

switch ( $_SERVER['SERVER_ADDR'] ) {

    // local
    case '' :
	$db['expressionengine']['hostname'] = "localhost";
	$db['expressionengine']['username'] = "root";
	$db['expressionengine']['password'] = "password";
	$db['expressionengine']['database'] = "local-db";

    // staging
    case '' :
	$db['expressionengine']['hostname'] = "";
	$db['expressionengine']['username'] = "admin";
	$db['expressionengine']['password'] = "password";
	$db['expressionengine']['database'] = "staging-db";

    // live
    case '82.335.65.67' :
	$db['expressionengine']['hostname'] = "";
	$db['expressionengine']['username'] = "admin";
	$db['expressionengine']['password'] = "password";
	$db['expressionengine']['database'] = "live-db";


At this point I want to distinguish between what I call environmental variables and universal variables.

  • Environmental variables are different on each server environment.
  • Universal variables are the same no matter which server the site resides on, so they go outside the IP switch/case syntax.

These are things like the server paths and URLs to the themes folder, template folder, CAPTCHAs, the license number, basically anything besides the aforementioned database information and IP address (these are all commented in the included file for reference).

Did you hear me say that server paths and URLs stay the same no matter what server you’re on? Yes you did. As long as your site’s folder structure remains the same in every instance (and if you’re on version control it obviously will), PHP variables detect the root server path and URL and fill them in for you. Why EE doesn’t do this to begin with baffles me, but I digress. No more forgetting to change the server path to your themes folder when you migrate servers and spending an hour figuring out why you have a blank screen instead of a CP. Anyone excited yet?

| ExpressionEngine Config Items

$config['app_version'] = "211";
$config['license_number'] = "0000-0000-0000-0000";
$config['debug'] = "1";
$config['install_lock'] = "";
$config['system_folder'] = "admin";
$config['doc_url'] = "";
$config['is_system_on'] = "y";
$config['cookie_prefix'] = "";
$config['site_name'] = "Flourish Interactive Codebase";
$config['allow_extensions'] = "y";

/* General
$config['site_index'] = "";
$config['site_url'] = "http://".$_SERVER['HTTP_HOST'];
$config['server_path'] = $_SERVER['DOCUMENT_ROOT'];
$config['cp_url'] = $config['site_url']."/".$config['system_folder'];

/* Universal database connection settings
$active_group = 'expressionengine';
$active_record = TRUE;
$db['expressionengine']['dbdriver'] = "mysql";
$db['expressionengine']['dbprefix'] = "exp_";
$db['expressionengine']['pconnect'] = FALSE;
$db['expressionengine']['swap_pre'] = "exp_";
$db['expressionengine']['db_debug'] = FALSE;
$db['expressionengine']['cache_on'] = FALSE;
$db['expressionengine']['autoinit'] = FALSE;
$db['expressionengine']['char_set'] = "utf8";
$db['expressionengine']['dbcollat'] = "utf8_general_ci";
$db['expressionengine']['cachedir'] = $config['server_path'].$config['system_folder']."/expressionengine/cache/db_cache/";

/* Member directory paths and urls
$config['avatar_url'] = $config['site_url']."/uploads/system/avatars/";
$config['avatar_path'] = $config['server_path']."/uploads/system/avatars/";
$config['photo_url'] = $config['site_url']."/uploads/system/member_photos/";
$config['photo_path'] = $config['server_path']."/uploads/system/member_photos/";
$config['sig_img_url'] = $config['site_url']."/uploads/system/signature_attachments/";
$config['sig_img_path'] = $config['server_path']."/uploads/system/signature_attachments/";
$config['prv_msg_upload_path'] = $config['server_path']."/uploads/system/pm_attachments/";

/* Misc directory paths and urls
$config['theme_folder_url'] = $config['site_url']."/themes/";
$config['theme_folder_path'] = $config['server_path']."/themes/";

/* Templates Preferences
$config['save_tmpl_files'] = "y";
$config['tmpl_file_basepath'] = $config['server_path']."/templates/";
$config['site_404'] = "404/index";
$config['strict_urls'] = "n";

// END EE config items

Keep in mind that a universal variable can become an environmental variable if you need it to. Let’s say that you want to change your site name automatically based on the server it’s on, so you can tell at a glance if you’re looking at the local, dev or live version of your site. Just delete the variable from the “universal variables” area and copy it into each IP case syntax, assigning it whatever value you want.

Step 3: Cleaning House

Let’s face it; the default install of ExpressionEngine includes a lot of files you don’t need, especially if you’re a professional developer who’s not poking around for the first time.

These include the theme files for the Agile Records example site, smileys, wiki themes, and a lot more. Why fatten your site unnecessarily? Put EE on a diet and delete all this stuff, you can always grab a fresh copy and add it back in the unlikely event you need it for a wiki, forum or other community-based site. Delete only what makes sense for you, but I’ve done about a dozen EE sites and never used any of it.

  • /themes/wiki_themes
  • /themes/site_themes/agile_records
  • /themes/profile_themes/agile_records
  • /images/smileys
  • /images/avatars

Step 4: Create a Standard Top-level Folder Structure and .htaccess File

Like many tasks in web development, there’s no one right way to go about this, but what’s important is that you pick a way and stick to it. Some people like to put their static asset files (images, css, js, swf, etc.) in a /themes/site_themes/examplesite folder. I prefer to put each asset folder on the top level because I’m lazy and don’t like to click through three levels of subfolders to access these files during development, plus I like nice short URLs in my HTML and CSS.

Now that I’ve gotten used to a standard structure, I do not create additional top level files or folders unless absolutely necessary (you’ll see why in a minute). This is what my top level structure looks like.

  • .htaccess – will explain more in a minute
  • system – rename this please
  • css
  • favicon.ico
  • fw – this is short for “framework” e.g. my CSS background images
  • images – non CMS-managed content images
  • index.php
  • js
  • robots.txt
  • templates
  • themes – CP and fieldtype themes
  • uploads – where all CMS-managed docs and images go

Now I get around to talking about .htaccess. It’s a mystery to many developers and frankly it is to me too, but I know enough to use it to remove that unsightly index.php from EE’s otherwise pretty URLs. I use a variant of the exclude method from the ExpressionEngine Wiki. This is in no way guaranteed to work on your web host, but it’s worked for me on MAMP Pro, HostGator and MediaTemple, both (gs) and (dv). The usual caveats apply, e.g. mod_rewrite must be enabled in Apache’s http.conf etc.

If you’re using this method of removing index.php and wish to add a new top level file or folder to your site (and I mean a “real” file or folder, not an EE entry, template or template group), you’ll need to add an exception in .htaccess or else that file/folder will be inaccessible.

Step 5: Install Your Default Add-ons and Configure Them

After developing several EE sites, there are add-ons I am either unwilling or unable to live without. These are the best the EE development community has to offer and they have the honor of being installed in my codebase so that every new site has them from the get-go. They are (and these are all free):

Don’t just install these, configure them. For example, I have set up all my email notification templates for Freeform, created additional custom form fields based on what I usually use for a standard contact form, and I have a template called contact.html which has the front end form code in it, including JavaScript validation and a success message. Even if I need to add a field or two, or move that form code into a different template, it’s a matter of tweaking, not creating from scratch every time. DRY. Minus CSS styling, that form is ready to go out of the box.

Be on the lookout for another article by me soon as I discuss these and a couple of commercial add-ons for EE2 in more detail.

Step 6: Set Up Your Client’s Member Group

Giving unlimited access to my client is scary for both them and me.

This is one of those things you likely forget to do until you’re nearly finished with the site, but it doesn’t need to be if it’s in your codebase. The default EE administrator account belongs to the Super Admins member group, which necessarily has access to everything. Giving unlimited access to my client is scary for both them and me, so I create a second member group called Admins. I usually wait until they’ve picked an email address before I actually make their account but that only takes a couple seconds once you have the member group permissions defined.

In this member group I’ve turned off all access to the templates, site and member administration, communication module, and add-ons. All that most clients need to do is create and edit content, and maybe view their Freeform submissions. That’s it. Simplify their life and yours and take away what they don’t need. Again, I’ve had to tweak this before but a starting point is better than starting from scratch.

Step 7: Working With Your Codebase

Congratulations, you should now have a far superior starting point for your next ExpressionEngine project. So that you can add to it and reuse it, create a new project in your version control and commit your customized ExpressionEngine codebase as version number one. Below are examples of some common operations you’ll likely need to do once you’ve got new projects in the pipeline (may vary depending on server setup, or if you’re using Git instead of SVN).

Create a New Project – 10 minutes

  • Clear all caches of your codebase project.
  • Export database and import under new project name using PHPMyAdmin or similar.
  • SVN export a copy of your codebase to the working copy folder of a new SVN project. VERY IMPORTANT: Note that I said export, not checkout.
  • Set the following folders and their contents to permissions 777:
    • /templates
    • /uploads (or whatever your upload folder is named)
    • /system/expressionengine/cache/db_cache
  • Add DB connection info for new DB to config.php. Change the site name, license numbers and any other preferences you need to change.
  • Load up your control panel and change the file upload preferences. These are stored in the database and cannot be put in the config for some asinine reason.
  • Go nuts.

Deploy a Site to a New Server – 10 minutes

  • Clear all caches.
  • Export and import database using PHPMyAdmin or similar.
  • Find IP address and database info and add a new IP case section to config.php.
  • Commit config.php to your repository.
  • Check out your site’s repository to the public_html folder of your new server.
    • If it’s a local server use your SVN client.
    • If it’s a remote server use the SSH command svn checkout . The space and dot after the trailing slash checks out the contents of the folder to the current folder, otherwise you’ll get public_html/sampleproject/index.php if you leave out the dot.
  • Set the following folders and their contents to permissions 777:
    • /templates
    • /uploads (or whatever your upload folder is named)
    • /system/expressionengine/cache/db_cache
  • Load up your control panel and change the file upload preferences.

Update a Site to an Existing Server – 1 to 5 minutes

  • Clear all caches (only if you’ve made changes to the database).
  • Export and import database using PHPMyAdmin or similar (only if you’ve made changes to the database).
  • Run an SVN update on your site copy:
    • If it’s a local server use your SVN client.
    • If it’s a remote server use the SSH command svn update. You shouldn’t need to re-enter the URL or password.
  • Load up your control panel and change the file upload preferences (only if you’ve made changes to the database).

Conclusion – Sojourning in the DRY Desert

As you go about your business designing and developing kick-ass ExpressionEngine websites, keep yourself mentally aware of what you’re doing at all times, from a big-picture, functionality perspective. Some pieces of website functionality are nearly identical across sites, they just need some minor markup tweaks and a CSS “skin” to easily transfer from one to another.

In the future, microformats will standardize the markup even more! These are ideal candidates for inclusion in your codebase. One we already discussed is the ubiquitous contact form. Some other potential “standard” functionality (I’ve had multiple clients ask for these things):

  • Blogs and their associated comment forms
  • Address or v cards
  • News release sections
  • XML or “Google” sitemaps
  • Search and search results pages
  • Custom Share This! type code
  • Facebook or Twitter timelines

You could theoretically have channels, categories, custom field groups and templates built out and ready to go (I know I do for a lot of these). Your client is still getting the same amount of value that they would if you hand-built these pieces for their site (arguably more since they’ll be refined and tested more often) and you do less work, meaning you can price yourself more competitively, or if you sell fixed fee, charge the same price and turn more of a profit. Remember to have fun and enjoy developing with ExpressionEngine!

October 27 2010


Turbocharge your ExpressionEngine 2 Education

ExpressionEngine, as a platform and a community, has seen a lot of growth recently. While there are some nice roundups out there about EE resources I thought it was time for a more relevant and up-to-date article to hit the streets. If you’re getting started, this set of resources will get you moving in the right direction. After all, I’ve walked this path myself thus far.

My Perspective

Before diving into the resources I should provide a bit of context to my approach to learning EE. I first looked at the software a few years ago and totally didn’t get it. I was already using the PHP framework CodeIgniter, made by the same company, and I saw no need to use EE if I could just build a CMS to do exactly what I needed. Regardless, I wanted to download and test out the software.

Straight out of the gate, I didn’t get it.

I was used to either WordPress or writing my own logic. ExpressionEngine installed with a bunch of “modules” and a few “custom fields” in which I could insert my data. I took a look at the official documentation and didn’t really understand how or why it was a powerful tool. After about 5-10 days of kicking the tires I just put it aside.

Fast Forward

Jump ahead two months, and I find myself back to testing out ExpressionEngine. This time, it was due to finding a series of tutorials on building a church website in EE. After reading the articles, I started to learn how EE was setup “out of the box” and where I could take it. Since reading those tutorials I haven’t put EE down and would consider myself an EE evangelist these days.

During my EE journey, I’ve discovered quite a few excellent resources and taken note of a few community leaders. Let’s dive in and see how they can help you learn ExpressionEngine 2.

(Possibly) Changing Mindsets

When I first dove into EE, I, as mentioned above, simply didn’t “get it.” Coming from WordPress, I was accustomed to working with a Title, Body and some extremely basic Custom Fields. I’d worked a lot with WP’s Categories, Tags, and Widgets, and was used to 1-click installs of templates and auto-updating software. EE is quite different…but I love almost every difference.

I won’t venture into explaining how things work in EE, but there are some great articles to check out. Firstly, I’d suggest reading “Switching Mindsets: From WordPress to ExpressionEngine,” by Mindy Wagner at Viget Labs. Her story is similar to mine in particular. Next I’d say, check out WordPress vs. ExpressionEngine: Apples and Oranges? by Marcus Neto. He talks about how the two handle content differently and provides excellent examples.

Okay, now that you’re eager to debate why one piece of software is “better” than the other, let’s change the topic slightly.

Community Websites

This year EllisLab, makers of ExpressionEngine and CodeIgniter, did something awesome. They welcomed some EE fan sites into the EllisLab family by making them “official community partners.” The sites collectively supply the EE community with the latest EE community news, short tips on using EE, a gallery of great EE-powered sites, articles on projects, the official repository of add-ons & more. Take a look at the community sites here:

And some great un-official community EE sites:

Official & Un-official Support

What I really love about the forums is the unofficial support.

EllisLab offers official support from their dedicated staff for any license holder of ExpressionEngine. If you’re having a problem with your site and can’t figure out what’s gone awry, they are good at helping figure things out. They provide this support, via their forums at Official support is quite nice for software like this.

What I really love about the forums is the unofficial support. The community of EE users is awesome and I’ve learned a lot from other developers via the official EE Forums. I’ve been a fan of forums since my moderating days at Flashkit; so I naturally jumped into learning about EE there.


I can’t help but give Train-EE a section of its own here. If you’ll remember from this article’s introduction, I turned away from EE rather quickly, at first. It wasn’t until I read through a tutorial series on Building a Church Site that I really started to understand how to use EE.

Long time EE user Michael Boyink created Train-ee when he saw a void in the EE learning process. Since creating Train-ee, Mike has written two EE books, published numerous online text and video tutorials and created the only to-date classroom training course for EE. Mike is also working with EllisLab to make the process of learning EE more seamless and formalized.

In short, Train-ee is an excellent learning resource for ExpressionEngine. Start with some of the free stuff, but definitely purchase some of the commercial goods. The small amount you spend on training is probably nothing compared to the time you’ll save slaving through EE without it.

Other Free and Paid Learning

Train-ee, of course, isn’t the only place in town for learning EE. Here are a few more ways to learn EE both on and off the web.

Online Learning

I personally got a lot out of the EE Screencasts series by Ryan Irelan. He’s also working with other developers on premium tutorials that go beyond the basics. Keep your eyes on his site for additional videos down the road.

Speaking of Ryan, he has his hands in a lot of EE resources. He also runs official community partner site EE Insider where you can get all the latest EE news and quick tips. They do a great job of keeping the community informed. EE Insider also hosts a weekly ExpressionEngine chat most Wednesdays. It is an open chat where you can come and ask questions and give ideas.

Ryan also co-hosts the EE Podcast with Lea Alcantara. This is a weekly podcast where Ryan and Lea and the occasional guest dive deeper and discuss topics like “E-Commerce and ExpressionEngine” and “SEO, Search Engine Optimization, ExpressionEngine“. The EE Podcast is definitely a great way to stay informed on EE techniques.

If you’re looking to extend what EE can do out of the box, then the place to go is Devot:ee created by Ryan Masuga. They provide a catalog of nearly all public EE add-ons to date and even offer simple software support and commercial sales to developers who might not want to host that on their own. Devot:ee is the first place I go when looking to extend EE. If the add-on exists, they probably know about it.

Offline Learning

There are numerous opportunities to learn EE live and in person. For starters, there is the EECI conference, which just saw its 3rd occurrence (photo courtesy of Nate Croft, FortySeven Media). It’s the largest gathering of EE nerds that I’m aware of. The speakers are top notch, and it’s a big heap of fun. The next iteration is in New York in October of 2011.

Aside from the big EECI, there are other conference opportunities out there. Just last week, there was EE Camp in Denver, Colorado. This week, there is the online ExpressionEngine conference EngineSummit 2. Numerous cities also have meetups for ExpressionEngine, which are great ways to share and learn in a small, informal atmosphere.

A slightly different approach to in-person learning is hiring a professional consultant. It’s a service typically used by companies with in-house teams working with EE. For example my company, Focus Lab, LLC, often does private training and consulting on EE topics. If you find yourself in need of a private instructor, the ExpressionEngine community certainly has those resources available.

Buy a Book

The last place I want to touch on offline learning is published books. There are a few to choose from and it would be silly not to mention them. The aforementioned Michael Boyink and Ryan Irelan both have published books on ExpressionEngine 2. There is also a book by Leonard Murphey, which is published by Packt Publishing. Certainly consider checking them out if you’re a book reader.

Dive in to the Community

EllisLab, themselves, have said their favorite feature of EE is the community. I have to agree! They have two full time staff members dedicated to the community; so that should tell you a little about them. Getting involved in the EE community is easy. For me, it began on the official EE forums. From there, I started tweeting a lot about EE and then publishing some of my add-ons publically on GitHub. Here are a few places you can look out for EE’rs.

Who to Follow

Since you’re ready to dive into ExpressionEngine 2, I thought it’d be nice to share some developer names with you. You know, the guys who are consistently doing awesome work and sharing ideas with others. This is by no means meant to be a complete list, but here are a few developers to keep your eyes on:

Link Roundup

To preserve your precious mouse index finger’s strength today I’ve provided you with a roundup of the primary links here:

I’ve overloaded you with resources. Now go forth and learn ExpressionEngine!

Already a Seasoned EE Pro?

If you’re already a seasoned Expression Engine pro, did you know that Envato’s rapidly growing marketplace for code, CodeCanyon, very recently launched a new ExpressionEngine extensions category? We’ve launched with a handful of seed extensions, however, we’re actively seeking new authors and contributions.

There’s no better time to join, as we’ve recently increased our author rates, once again, to 50-70% of every sale. With countless authors making four+ figures in income every month, now is the perfect time to jump in. If you have any questions, leave a comment in this thread, and I (Jeffrey) will get back to you ASAP.

Premium EE Extensions on CodeCanyon

  • Mapper: Display Google Maps on your site with ease.
  • Widgets: Widgets is a ExpressionEngine 2.1 module that allows even your least experienced client or to manage chunks of intelligent content on there site without needing to learn loads of tags, HTML or call you in to help.
  • Multi-Language Support: This extension provides the foundation for multi-language support in your website.

March 22 2010


A 15 Minute Surreal CMS Integration

You’ve already built your website, but how are you going to maintain it? In this tutorial, you’ll learn how to integrate your website with Surreal CMS in under 15 minutes. We’ll go over some of the “gotchas” and have you editing virtually any static website in barely no time at all.


You’re probably wondering how you could possibly integrate your entire website with a CMS in just 15 minutes. The truth is, due to the recent trend of “light” content management systems, it’s becoming easier than ever to get small to mid-sized static websites up and running in them.

What is a light CMS? For the sake of this tutorial, I’m defining it as an easy-to-use, unobtrusive content management system that you don’t have to install. The nice thing about these systems is that you don’t even have to host them yourself, which is why integration takes very little time.

There are actually a handful of these CMS products available, including CushyCMS, Pagelime, and SimpleCMS. Most of these systems work off the same basic principle — you add class=”something” to almost any HTML element, link your website up to their system, and you’re done. Best of all, every one of these systems offer a free version.

Although every light CMS product has its pros and cons, I chose to work with Surreal CMS because of their vast feature set and simple interface. You’ll see exactly what I mean in just a moment, but in the meantime, here is the general process of integrating with any light CMS:

  • Create your website
  • Link it up to the CMS
  • Enable webpages
  • Add one or more editors
  • Begin editing

Just to familiarize you with the tool that we’ll be working with, here is a quick glimpse of Surreal CMS’ webpage editing screen:

Design Considerations

Before you begin working with a light CMS, it’s always good to think about things such as character encoding and the way you link to images and other resources. Surreal CMS prefers that you use UTF-8 character encoding, which is as simple as adding the following meta tag to the <head> section of each webpage:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

It’s also important that you link to documents, images, and other resources in a way that the CMS can understand. Surreal CMS works best when you use root-relative linking or absolute linking:

<a href="/images/photo.jpg">...</a>
<a href="">...</a>

The last but probably most important thing to consider before linking your website up to Surreal CMS is the placement of your content regions. Here is an excellent example of a very basic webpage that has a navigation menu, a sidebar, and a main content area:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns="">
		<title>Example Webpage</title>
		<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
		<meta name="description" content="This is an example webpage" />
		<meta name="keywords" content="example, examples" />
		<link href="/css/screen.css" rel="stylesheet" type="text/css" media="screen" />


		<div id="header">
			<h1><a href=""></a></h1>

		<div id="nav">
			<?php include("$_SERVER[DOCUMENT_ROOT]/includes/nav.php"); ?>

		<div id="middle">

			<div id="sidebar" class="editable">
				<p>Sidebar content here</p>

			<div id="main_content" class="editable">
				<p>Your content here</p>


		<div id="footer">



You may have noticed that I added editable classes to the sidebar and the main content region. This is how the CMS knows what sections of your page it should allow you to edit. You can add the editable class to almost any HTML tag, and you can have as many as you want on each page.

Another thing you may have noticed was that the navigation is being included from a separate file via PHP. Surreal CMS allows you to work with included files like this so you can update your entire site’s navigation without having to edit each page individually.

Once you’ve prepared your pages and setup editable regions, you’ll be ready to integrate your website with Surreal CMS.

Adding Your Website to the CMS

Surreal CMS offers both free and paid accounts. The free account has very few restrictions, and will be more than sufficient for the sake of this tutorial. Simply go to their website and create a free account.

Once your account is created, login to the CMS at This is the gateway to the Surreal CMS application.

Now that you’re in, select the button that says Add a Website. Here is the form that you will see:

Enter your website’s URL, server (usually, FTP username, and FTP password. You can verify that you typed everything correctly by clicking Test Connection.

For the Website Root, it’s best to click the Browse button and use the browsing tool. Essentially, your website root will be the folder that contains your homepage. It’s important that this folder be the actual folder that has your homepage so the CMS can properly map URLs to images and other files.

If you want to specify custom paths for documents, images, and media files, select the Advanced option. When you set custom paths, it will tell the CMS where other people who are editing your website are allowed to upload files. For now, you can leave these blank.

Enabling Your Webpages

Now that your website has been added to the CMS, the next step is to enable your webpages. In other light CMS products, this can be a bit taxing on your time, but Surreal CMS has a nice scan feature that auto-enables webpages with just a click.

To begin enabling pages, select your website from the list:

Next, select Enable Webpages. The following dialog will appear:

Select the page or pages that you want to be able to edit in the CMS. As you select them, they will appear one-by-one in the background. As a shortcut, you can navigate to any directory on your website and click Scan for Editable Pages. This will tell the CMS to enable any page in the current directory that has a class=”editable” attribute in it. When you’re finished, select Done.

By default, each page that you enable uses the <title> of the page as a label. You can easily change this to something more CMS-friendly by clicking on Edit Label. For example, you might change the label for index.php to read “Homepage” and the label for nav.php to read “Navigation”.

Updating Your Content

Believe it or not, the hard part is over. Now it’s just a matter of getting in there and editing content. Part of the reason I like Surreal CMS so much is that it streamlines most of the setup. That said, let’s move on to editing content.

After you enable one or more webpages, the next step is to begin editing. Simply select any of the pages that you’ve enabled by clicking on the appropriate page label. This will take you into the webpage editor, where you’ll spend most of your time using this great CMS.

In the webpage editor, you’ll see four tabs:

  • Content – This is where all your content regions can be found.
  • Properties – You can edit the page title, keywords, and description here.
  • History – View every revision of this page that gets published for up to 90 days.
  • Editors – See a list of all the editors that have access to the page.

Inside of the Content tab, assuming your page has at least one editable region, you’ll see something like this:

This particular example has the two editable regions we talked about earlier: sidebar and main_content. You’ll notice that the CMS converted the lowercase, underscore-separated IDs into Camel Case, space-separated labels for aesthetics. If you have more than one editable region on a page, you can switch between them by clicking on the appropriate button.

At this point, editing works the same way as it does in many other content management systems and word processing applications. You can format text, change alignment, insert images, lists, etc. Surreal CMS even has a built in File Manager that lets you view, upload, rename, and delete files and folders. To top it off, there is also an Image Editor that lets you resize, crop, rotate, and flip images with ease.

Depending on the type of element that you add class=”editable” to, Surreal CMS will provide an appropriate editing tool. As an example, here is what an editable <img> looks like:

The Edit Image button launches the Image Editor that I talked about earlier. It’s really easy to use, so you shouldn’t have any trouble at all manipulating your photos. Here’s what it looks like:

Once you’re finished editing, you can preview your changes by clicking Preview. A new window will open, and you’ll see your page exactly as it will appear when published. Of course, if you’re happy with your changes, clicking Publish will save them to your website.

Allowing Other People to Edit Your Website

Now that you know how to setup your website and edit it yourself, wouldn’t it be nice to allow other people access as well? This is especially useful for designers who want to give clients limited access to edit their own websites, and it’s simple to setup.

First, select the Editors tab from anywhere in the CMS and click on Add an Editor. The following form will appear:

Simply fill in the person’s name and email address to start. Then, select the website(s) that he or she should be assigned to. If you want, you can open up the Advanced section and allow the editor to clone pages, delete pages, and edit page properties. You can also enable or disable every option in the rich-text editor toolbar from here.

Once you’ve entered all the necessary information, select Add Editor and the user will be added to the CMS. By default, an email is sent to them containing their username and password. You can disable this, however, and the CMS will show you their temporary password for you to provide them with manually.

There are a couple things that you need to know about editor accounts. First, they don’t have access to everything that you do as a designer — editors only have access based on the websites and permissions that you assign to them. Second, editors don’t have access to things like full-page source code editing and the Tidy tool, which we’ll talk about shortly. The best way to see what the difference is between a designer and an editor account is to create yourself a test editor with an alternate email address.

Before we move on, there’s one other feature that you should know about editors. You can block them from editing specific pages on a per-user basis. Simply open any page for editing and select the Editors tab. Next to your editor will be an option to Disable editing. Clicking this will prevent that user from editing the current page.

Other Handy Features

So far, we’ve covered everything from integrating Surreal CMS with your website to editing pages. The fun doesn’t stop there, though. Here is a list of features that you can take advantage of once you start to explore deeper into what Surreal CMS offers:

Cloning Webpages

You can create new pages by duplicating existing ones. This is especially useful because you can setup one or more blank template pages and let your users create pages as they need to. You can also turn this on or off for each user, so more experienced editors can have more control over the site.

Styling the Rich-text Editor

Apply styles from your website to the rich-text editor to give users a similar look and feel similar to the website. To access this feature, select the Websites tab from anywhere in the CMS and choose a website. You’ll see a button labeled Change Editor Styles.

Editing CSS, JavaScript, and XML Files

You can enable stylesheets, scripts, and XML files just like any other webpage. Of course, you’ll be editing raw source code, so you might want to block inexperienced users from accessing these types of files if you enable them.

Editing Full HTML Source Code

While you’re editing a webpage, you’ll notice a button labeled “Edit Content Regions”. This actually allows you access to the full source code of the page. Editors do not have access to this tool.

Repairing Messy HTML Code with Tidy

Surreal CMS has a built in tool that utilizes the popular HTML Tidy library. This is useful for fixing nested tags or invalid HTML code that may cause problems while editing. You can access this tool from within the full source code editing page.

Viewing Editor Activity

You can see what your editors have been up to! This includes what pages they’ve accessed, when they were edited, and even the times that they logged in to the CMS. To view this information, select the Editors tab from anywhere in the CMS and choose an editor. Click on the editors name to see their recent activity.

Pro Features

Surreal CMS is free to use for up to three websites. After that, they ask you to pay $25 USD per month for their paid service, but Pro accounts have a couple other nice features, too. For example, you can access the CMS from your own domain or subdomain (i.e.

With a Pro account, you can also upload your own logo and customize the theme, which is ideal for designers who want to use the CMS as a solution for their clients. Here’s an example of what you can expect when you brand the CMS as your own:

Additional Resources

Now that you know all of the basics (and some advanced tips, too!), here are some useful resources for working with Surreal CMS:

Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.
No Soup for you

Don't be the product, buy the product!

YES, I want to SOUP ●UP for ...