Meganto: Make A Magento 1.6 Theme From Scratch

This is the all-inclusive guide to Magento 1.6 theming: from the installation to a finished product.

  1. Installing Magento 1.6.1
  2. Creating The Database
  3. Set Magento Up For Development
  4. Starting Our Theme Development
  5. Enabling The New Package and Theme
  6. Creating The Homepage
  7. Setting Template Layouts for CMS Pages
  8. Implementing Proper Magento Template Practices

1. Installing Magento 1.6.1

This guide will use Ubuntu as the operating system of choice. If you aren’t running a Linux distribution, you may run into some problems that won’t be covered in this guide. Did you know Ubuntu was free? Get it here and run a dual boot, or even run it as a virtual machine.

Using Subversion to Grab The Project

Let’s create the Magento directory we will be working in and then download the project via Subversion.

It’s possible the above URL will change. A minor release may come about or the branch will be moved. In that case, you may find details you need on the Magento SVN page.

2. Creating The Database

Magento uses MySQL for its database. You will need MySQL installed and change out the username to fit your own. I’m using a super user, so in your case you might have to create your own Magento user and assign privileges accordingly.

Setting Up The Virtual Host

We will be accessing the project through the http://magento.local/ path. First we tell Ubuntu to redirect any traffic to that domain to our localhost, then setup Apache to handle the request.

Add this line:

Now create a virtual hosts file that tells Apache how to handle our request. 000-default is probably already in your Apache2 folder. If you don’t have any other vhosts setup, you’ll want to create 001-magento.

Add this to the file:

Restart Apache and check it out!

If things went well you should see the install. The install process is simple, so let’s skip to setting Magento up for development.

3. Set Magento Up For Development

Developing on Magento is a pain if you are using the settings for the production environment. Let’s make development easy on ourselves!

 File Ownership and Permissions

Since we are working on development, we can skip some headaches from permissions and ownership issues:

Check the owner of the files, and recursively use chown if necessary.

Disable The Cache

It’s fantastic that Magento comes with the ability to cache everything and anything, but this is poor for development. Save yourself from clearing the cache on each change by disabling it completely.

  1. Go to System -> Cache Management
  2. Select all and disable
  3. Success!

Disable Magento Cache

Enabling Errors

When something goes wrong we want to know about it. In your index.php file simply uncomment line 70:

4. Starting Our Theme Development

There are two main parent directories that will be used to run a theme.

  1. /app/design/frontend/ – This contains all the logic and markup for your theme.
  2. /skin/frontend/ – This contains all the styles, javascript, and images for your theme.

Look around a bit. There are a lot of files! It may seem easier to copy an existing theme and hollow it out to make your own. This is a bad idea: there will be quite a bit of excess code, and you won’t learn the Magento theme structure as you should.

Create a New Package

Before we get started, a word of caution: never edit the base package. It contains all the fallback files that are used when Magento can’t find a certain file. In addition, a Magento update will overwrite changes to the base package.

A package may contain a number of themes. For instance, you will see the default package has a default and modern theme. If you wanted you could create a new theme inside the default package, but we are rolling our own named Vacancy:

  1. Create the package templates folder: /app/design/frontend/vacancy-package/
  2. Create the package styles folder: /skin/frontend/vacancy-package/

Alright chief, this is your directory structure so far:

New Magento Package

Create A New Theme

You may have multiple themes for each package. Our package will actually have two themes: default and vacancy-theme. The base package works as a great fallback, but we will be copying the default theme to our own package. Then we won’t have to touch any files that aren’t pertinent to our project.

Copy from and to:

Excellent. Now if Magento can’t find a file, it will use our package’s default theme to find it. Just like the base package, you shouldn’t edit this theme.

No need to copy over your styles and images: we will be using our own basic design for this tutorial.

The game so far:

Copy Default Theme

5. Enabling The New Package and Theme

Magento doesn’t yet know we want to use our own package and theme — let’s tell it!

  1. Go to System -> Configuration
  2. Go to General -> Design
  3. Add in our package and theme like so:

Default Design Config

Refresh the home page and you will see an un-styled beast of a theme. Let’s get Vacancy styled, shall we?

6. Creating The Homepage

The base theme we are working with is dubbed Vacancy. It’s a high-end design, as you can see:

Vacancy Theme

Alright, maybe not high end, per se, but for our purposes it will explain the concept of themes famously.

Your skin directory should look like this once you plop in the CSS file:

Skin Directory

You won’t directly use the index.php file, but you should still take a good look at it. It gets chopped up into sections, modules, and blocks before we are able to use it in our actual theme.

Working With Magento XML Layout Files

Magento uses XML files to pass important layout information to our view. This could include a module, template file locations, or adding Javascript files to our header.

In the default theme, you will see three major folders:

  • etc
  • layout
  • template

We are concerned with the layout and template folders. Layout contains the XML files, while the template folder contains PHTML files.

The XML files structure the content by blocks, while the PHTML files contain our actual markup. This should be more clear when we work with these files more.

To get an idea of this concept, open two files from the default theme:

  1. /layout/page.xml – This contains the mentioned structural code. Our own page.xml will be drastically simplified.
  2. /template/page/2columns-left.phtml – This contains markup for one of the default layouts, which has two columns and a left sidebar. As you can see, Magento simplifies the layout to a great extent by allowing for blocks and sections to be included as needed.

Let’s create our own page.xml file — this will be the default fallback for all pages. Ours will be a hollowed-out version of the version you just saw:


It’s a good time to review blocks. In Magento, blocks serve the purpose of grouping together items in your template.

In our case, our blocks are the head, header, sidebar, content area, and the footer.

You will notice that the root block references a template file, vacancy-2columns.html. Let’s create that now.


Vacancy Layout

For now just put the contents of our index.php file you downloaded earlier and save it.

Refresh the page.

Doesn’t work too well, does it? That’s because the homepage in Magento is currently a CMS page. In your admin panel:

  1. Go to CMS -> Pages
  2. Go to Homepage -> Design

In the dropdown to select the design for the homepage you will note our theme and package is there, but our layout isn’t. The dropdown is being populated by an XML file so it isn’t dynamic.

And now more bad news: editing this dropdown isn’t as easy as you would think.

7. Setting Template Layouts for CMS Pages

There are two methods of altering your CMS page layouts.

Creating a module is the accepted way, but by simply making a module we won’t be able to remove the base layouts from the list. Not a big deal, but for the OCD impaired it’s sure painful.

Extending a core Magento file is the second way, and it has the benefit of giving you full control of what is in the list. The problem is that we are extending a configuration file — this is generally looked down upon because upgrades might significantly change the file. That means work will have to be done to update your installation before upgrading. This is somewhat a non-issue: if you have extended core files, you should already know that you’ll have to take a look at them before upgrading.

We’ll go through both methods since they both teach valuable lessons. Afterward you may decide which you want to side with.

Method 1 – Extending Magento Core Code

Magento keeps it’s base code in /code/core/Mage/. Do not ever modify these files directly. Your changes will be overwritten when you upgrade Magento. Instead, we have to extend the core files.

The files we want are located in:

  1. /app/code/core/Mage/Page/etc/config.xml
  2. /app/code/core/Mage/Page/etc/system.xml

Copy both of these over to a new path:

  • /app/code/local/Mage/Page/etc/

Look at the config.xml file and you’ll see how templates are being built. Just remove the <layouts> code and put the following in:


We don’t actually modify system.xml. Since there will be no fallback, we have to include all original files whether we modify them or not.

Now let’s tell Magento to use our local code instead of the core code! Find Mage_All.xml here:

  • /app/etc/modules/

Find the Mage_Page block and tell it to use local code like so:


If all went well you may now go to your CMS Homepage settings and use our theme:

Custom CMS Dropdown

Refreshing the homepage, you should see that we are now using the new layout. The CSS shouldn’t load correctly at this point. We’ll get to that after reviewing the second method of changing CMS layouts.

Method 2 – Creating A Magento Module

Creating a module is easy. We create a new XML file in /etc/modules/ named Vacancy_CMSTemplates.xml.

Fill your XML file with the following code:


Note that we named the module “Vacancy_CMSTemplates” – this is important to remember as it also tells Magento where our module code will reside. In this case we create our config.xml file at the following:

  • /app/code/local/Vacancy/CMSTemplates/etc/config.xml

The XML file will have to tell Magento to add our own layouts to the global scope. All we do is add our same XML layout code like so:

Before changes take effect we have to edit Mage_All.xml again and tell it to use the core code instead of our extension:


Add Templates via Module

Looking good! It’s also worth noting that if you wanted to quickly disable your changes, you could disable the module in the admin panel instead of removing your code. Oddly, the list of modules is conveniently dynamic! Hmph!

  • Go to System -> Configuration
  • In sidebar: Advanced -> Advanced

Now just disable it:

Disabled module

.. and that’s a wrap! As for me, I’m fine sticking with the extension method.

8. Implementing Proper Magento Template Practices

So far we only have a static layout. And one without style, no less. Let’s set up different files for the header, sidebar, content area, and footer.

Create the HTML template folder: /app/design/frontend/vacancy-package/vacancy-theme/template/page/html/

The /html/ folder will house three of the key template files for pages.

  • head.phtml     – Contains items such as meta info, page title, CSS/JS, and so forth
  • header.phtml  – Contains header markup such as the logo, header navigation, etc
  • footer.phtml   – Our footer box at the bottom of the page

Our sidebar doesn’t quite fit under the /page/ templates, so we will create a new folder for the navigation. Create sidebar.phtml at the following:

  • /vacancy-theme/template/catalog/navigation/sidebar.phtml

Our Head – head.phtml

All the meta info, helpers, includes and styling files are quite simple to load dynamically, thanks to Magento. The code should be straightforward:


Nothing here to change. Remember our page.xml layout block where we added the CSS file? That gets called with the getCssJsHtml helper. Automatic handling of meta tags is nice too.

The Header – header.phtml

Nothing too complex here – just outputting a simple welcome text. It’s set in the administration panel. Kind of useless, but let’s add it anyway:


The Sidebar – sidebar.phtml

For the sidebar we use a Magento helper to load all the categories and then loop through them, displaying them one at a time.

First, however, you need the categories to loop through! The administration panel is easy enough to use, but make certain that the categories you create are under “Default Category” for now. After you are done you’ll see something similar:

Add categories

Now for the sidebar.phtml file:


If you want to learn more about helpers like getName, your best bet is to get the class name of the object and search the Magento docs, or to do some sleuthing yourself.

Something like this does famously:

That will output all of the data from the Varien_Data_Tree_Node object ( which I found by echoing get_class($cat) ), allowing you to easily see what data is accessible. You can get any of the data by calling the proper method. Here’s example output of the data:

If you want the url_key data for the category “Pokemon Cards,” you’d use the following method:

You’ll be diving into code like this often with Magento: the official and community documentation is often outdated or just not helpful.

The Footer – footer.phtml

The footer also contains dynamic content. We will introduce the concept of Static Blocks in this section. A static block is a block that can be edited within the administration menu. In our case we will make the footer links easily edited.

Magento has already created our footer static block for us. You may see them if you go to CMS -> Static Blocks.


The syntax for getting a block from the CMS menu is easy. If you want to include a different block, just switch ‘footer_links’ with the block identifier, which you set in the edit menu for the block.

The Template File – vacancy-2columns.phtml

Now let’s bring it all together. Our template file will piece all of the phtml files we just created together.


So this is fairly simple. With getChildHtml we are simply telling the layout to find the block within quotes. If you look at your page.xml file you will see that the names here correspond to the names of each block we created.

The Result

If everything went according to plan, you should have this for a homepage:

the big finish

You may download the contents of /vacancy-package/ for the skin and app directory here: