WordPress Theme Template & Directory Structure

Update: We’ve created a second edition of this article, with updated code samples and coverage of the latest theme development techniques. Check it out at WordPress Theme Template & Directory Structure. It’s part of The ThemeShaper WordPress Theme Tutorial: 2nd Edition.

While the most minimal of WordPress Themes really only needs an index.php Template and a style.css file (or just the style file if it’s a Child Theme) most WordPress Themes need something a little more solid.

Our new minimal will include 6 files. Make a folder in wp-content/themes/ for your theme—for this tutorial I’ll be using “your-theme” but it can be whatever you want—and create the following files in that new folder (don’t worry, they’ll be blank until the next few steps).

Now let’s open up the last file we created, style.css, in a text editor. The first thing we need to do is add a section at the top of this file bracketed by what are called CSS “comments” (these guys: /* and */). It’s here that we need to put the info that tells WordPress about your theme. Without it, your theme won’t show up in the themes panel.

Theme Name: Your Theme
Theme URI: http://example.com/example/
Description: A search engine optimized website framework for WordPress.
Author: You
Author URI: http://example.com/
Version: 1.0
Tags: Comma-separated tags that describe your theme
Your theme can be your copyrighted work.
Like WordPress, this work is released under GNU General Public License, version 2 (GPL).

Something to note: a lot of this is optional. Really, you just need the Theme Name. But if you ever plan on releasing your theme, or if you’re making a custom theme for someone, you’ll want to start out including most, if not all, of the rest. At the very least, I want you to feel free to mess around with it.

Once you’ve got that done you can activate your theme and navigate to your test site. We’ve made the ultimate blank theme! Things should start to get interesting right about now.

Building In Your HTML Structure

Now we get to use our HTML structure from the previous lesson. But first a mini-lesson about WordPress and Templates.

WordPress really only needs 1 template file, index.php. We can, and will be adding a series of template files that can be used instead of index.php for certain situations (single posts, category pages, etc.), but at the very beginning, index.php is all we’ll need.

Now, index.php and all it’s related brothers and sisters (which we’ll get to) make the web pages we see in our browser. They’re files with some HTML and HTML-outputting-PHP but in the end they make web pages.

Let’s think of web pages like stories, something with a beginning, a middle, and an end. Well, when we write out our index.php file (and later our single.php, category.php, etc.) we’re going to concentrate only on the middle bit. But! We’re going to call in the beginning bit and the end bit. We may have to always be redoing our middles but we’re only going to do the beginning and end of each web page once.

Header.php and Footer.php

Get the HTML structure we worked on in the previous lesson and copy everything up to and including

into header.php and save it. It should look like this:

<div id="wrapper" class="hfeed">
	<div id="header">
		<div id="masthead">

			<div id="branding">
			</div><!-- #branding -->

			<div id="access">
			</div><!-- #access -->

		</div><!-- #masthead -->
	</div><!-- #header -->

	<div id="main">

Now, copy everything after, and including,

into footer.php. It should look like this:

	</div><!-- #main -->

	<div id="footer">
		<div id="colophon">

			<div id="site-info">
			</div><!-- #site-info -->

		</div><!-- #colophon -->
	</div><!-- #footer -->
</div><!-- #wrapper -->


I bet you can guess what we have to do now. Copy everything from our HTML structure inside the #main div into index.php. It should look like this:

		<div id="container">

			<div id="content">
			</div><!-- #content -->

		</div><!-- #container -->

		<div id="primary" class="widget-area">
		</div><!-- #primary .widget-area -->

		<div id="secondary" class="widget-area">
		</div><!-- #secondary -->

With only two small additions we’ll have a perfectly invalid WordPress Theme but we’ll be on the right track. We need to call in the header and footer to your theme.

At the top of index.php, before anything else, add the following template tag.

<?php get_header(); ?>

I think it’s pretty obvious what this tag does. It gets the header. But while we’re here, take a good look at this template tag if you’re new to PHP. I want you to notice a few things. First, our PHP function call—get_header()—begins with . Secondly, while our call is only 1 line long it ends with a semi-colon. Small, but important stuff.

Alright! Can you guess what function call we’re going to put at the bottom of index.php?

<?php get_footer(); ?>

Yep. Now we’ve got our main file that WordPress looks for, index.php. It has all the middle bits of our web page, but the top calls in the beginning bits, and the bottom calls in the ending bits.

Reload your page in the browser and check out the source code (View > Page Source, in Firefox). Look! It’s your code!

You’re on your way to making your first WordPress Theme.

How To Create a WordPress Theme

This post is part of a WordPress Themes Tutorial that will show you how to create a powerful WordPress Theme from scratch. Read it from the beginning and code yourself up something awesome.

WordPress Theme Tutorial Introduction
Theme Development Tools
Creating a Theme HTML Structure
Template and Directory Structure
The Header Template
The Index Template
The Single Post, Post Attachment, & 404 Templates
The Comments Template
The Search Template & The Page Template
The Archive, Author, Category & Tags Template
The Sidebar Template
Reset-Rebuild Theme CSS & Define Your Layouts

61 thoughts on “WordPress Theme Template & Directory Structure”

  1. Get the HTML structure we worked on in the following lesson

    You mean the preceding lesson, I think.

    Very useful series so far.

  2. These articles deserve to be proof-read. (I mean that in a good way, that they will be read and re-read.) You said:

    Get the HTML structure we worked on in the following lesson

    Should that be a ‘previous lesson’.

    This leads me to wonder whether some journaling facility in WordPress would be useful. As it is off-topic, I pursue the idea in a very brief article on my blog.

  3. very clear series looking forward to the rest of the articles. a lot easier to follow that all the other wordpress theme creation tutorials so far. great job

  4. I think this is awesome. Through these lessons I’m actually beginning to understand some of this stuff. Great job, thanks!

  5. WordPress Themes really only needs and index.php
    should read :
    WordPress Themes really only needs an index.php

  6. hey ian, i’m also learning from your tutorial series to hopefully catch up with wordpress. the lessons are good so far, but i think, in the beginning, you should focus a little more on explaining the terms you’ll be using for the rest of the series by breaking your tutorials into smaller steps.

    the part about templates files as a story with beginning, middle, and ending is a little bit confusing when you’re already using terms like header, body, and footer. i understand what you’re talking about, but i’m not sure it’s clear to the newbies. i think it’s easier to understand if you stick with the head, body, and foot theme. i.e: sub templates like category.php and single.php are arms and legs.

    the previous lesson introduced html, but you didn’t explain basic rules like tag nesting. also, throwing little stuff like microformats in at the beginning is a little bit too much to absorb.

    originally, i wanted the wpdesigner tutorial series to be around 14-16 lessons, but i ended up with more than 20 lessons because the more i slowed down, the more readers were getting it.

    looking forward to your next lesson, good job dude.

    1. If someone doesn’t get something, I’ll explain it in the comments. If a lot of people don’t get a lot of something, I’ll insert a step in the tutorial series. But I have high hopes and high expectations of my audience! 🙂

      Really, the only way to learn is to try and fail. Fail spectacularly, actually. If a reader doesn’t get something, great. If they don’t get something and they really want to know where they went wrong, even better. You could break a tutorial into a 100 lessons with 100 steps but if a reader doesn’t try to understand something and fail, to later try and succeed, they’ll never get it.

      1. 100 lessons with 100 steps is overkill, but i’d bet you’d have a higher success rate. it saves you time and energy to help readers get it the first time around, not everyone search comments for answers. especially with a series like this one, you’ll be getting lots of comments. anyway, keep it up.

      2. Very well said. You’re like a strict teacher who expects nothing less from his students. You don’t spoon-feed us, instead you stimulate our brains and let us experiment for ourselves. 4 down and 8 to go!

      3. Hey Ian,

        I’m having some trouble with this part, WordPress Theme Template and Directory Structure. (Just for clear understanding, I use a Mac.) When you tell us to make the 6 files in this folder: wp-content/themes/Nikki (for my example)

        * index.php
        * header.php
        * sidebar.php
        * footer.php
        * functions.php
        * style.css

        These are supposed to be in my USER files on my mac right? Not in PhpMyAdmin?
        So, if this is true, I did that and followed all the steps on this page, and at the end you had us refresh the browser and click on view source (with Firefox). I did this and there was nothing in the box… and then I went to my admin for my wp, and my theme “Nikki” is gone. So, is there something I did wrong that you can help me with? I’ve redone this twice and it happened both times.

      4. Okay, backtrack to my last comment… My theme Nikki is still active, just the code source doesn’t show up when I click View Source. =/

        I hope I didn’t do anything too terribly wrong!

  7. Ian,

    Magnificent! I can already see what you said about lean markup. One question. If it does not matter?, why did you open the DIV at the end of the header.php and not after the call for the header in the index.php.



    1. That—that’s a very good question. One I’ve been thinking about myself. I may change that and update the code when we’re all done.

      1. … but then you’d also have to put these into index.php :
        (note that angle brackets have been omitted)

        ?php get_footer(); ?

        /div !– #main —
        /div !– #wrapper —

        So it seems the logic is that you use header.php to initiate *html*, and you use footer.php to terminate it */html*.

        Index.php is only used for the content area and widgets.

  8. Small Potato and Ian. I would like to share with both of you as I have been on both your sites. Steps are not important to me. I take them 1 at a time. It’s what is in each step that counts and does each step get me ready for the next one. You both write great tutorials. Ian is presenting, from what I have been reading the last 6 months, a truly structured format that can possibly be used in future projects. I think once e get down to the meat and potatoes ( no small ) Ian will have to draw us together and I believe he will. For the past year I have read more code that most people have and I will say there are a lot of varieties. Kudos to both of you for what you do.

  9. Ian, instead of a zillion screen captures, could we access the ‘your-theme’ front page to see if it matches what we are doing



  10. I spy a typo.

    Now, index.php and all it’s related brothers and sisters (which we’ll get to) make the web pages we see in our browser.

    Should be its instead of it’s, yes?

    On another note, I like how each piece of the themebuilding is in bitesize portions. It’s slow, but it’s not intimidating or confusing.

  11. Hi Ian,

    I wanted to say hello and thank you. This is exactly what I was looking for in order to be able to build my own themes, or modify others.

    I appreciate the step-by-step approach, and your knowledge of programming structure and search engine optimization issues is outstanding.

  12. Hey,

    Thanks for writing this up! It’s a big help!

    I have a problem, though. When I try to view my test website in this step it just shows up as blank. There’s nothing on the page. I can use the editor and see all my code in there as it should be, but the actual site shows nothing up.

    Is this normal, or is there something wrong?

    I’m using XAMP with mostly default settings for my server. Thanks!

  13. hi! thanks for writing up a tutorial – decided to give this a go (creating own themes).
    However, I don’t understand what went wrong – instead of a blank page, I get 3 lines of gibberish (to me it doesn’t make sense) – and I’ve followed everything.

    The weird thing is that, the same lines will appear right at the top of my admin page when I activate my test theme – when I activate the default theme provided by WP, the gibberish lines would not be there. I’m guessing it’s my theme that’s creating this havoc but I can’t find what’s the problem because I’ve done everything you’ve mentioned here.
    I’m using MAMP.

    The lines are – “{rtf1ansiansicpg1252cocoartf949cocoasubrtf460 {fonttbl} {colortbl;red255green255blue255;} paperw11900paperh16840margl1440margr1440vieww9000viewh8400viewkind0 }{rtf1ansiansicpg1252cocoartf949cocoasubrtf460 {fonttbl} {colortbl;red255green255blue255;} paperw11900paperh16840margl1440margr1440vieww9000viewh8400viewkind0 }”

    1. oh. I found the reason for the appearance of those lines but don’t know the reason or how they got there. it’s in my php files (all the blank files I saved under the theme folder) – all the php files had the lines when it’s in thumbnail/preview form but when i open the file, it’s blank. it’s weird – have you come across this problem before?

      1. Sorry to flood your comment section but I found out that those gibberish lines appear when I use TextEdit and change the extension from rtf to php. I don’t know what else to do but I just made copies of the other php files from the default theme, paste it into my new folder and deleted everything in those files and voila. Done…for now.

  14. Hi, I am new to WordPress and Xampp. You’ve written a great tutorial. However, I was stuck at the last step. Could you please give me some hint? Any help would be really appreciated. Thanks so much. I followed each step but got the following error.

    Fatal error: Call to undefined function get_header() in C:xamppxampphtdocsfirst_testindex.php on line 1

    1. I have the exact same problem.

      I thought it might be XAMPP so I uploaded it onto my website hosting providers server and got the same error message so that eliminates XAMPP. I’ve copied and pasted the code to the letter, I’m using dreamweaver to upload the files but still no joy.

      I’m wondering if its something to do with file permissions?? but like you I’m a newbie so not really sure

      1. Hi – you have to upload to the wp-content/themes folder. It appears you have uploaded to the root folder for WP.

        I too am a beginner in WP, so if I am wrong, someone please correct me.

      2. I don’t think I gave enough information on how to solve the issue. Please replace the index.php, with the original index.php which came with the downloaded WP archive. This tutorial is about files in the wp-content/themes/ folder, so ensure that you are in that folder.

        To preview what you have done, you can use the ‘preview’ feature in the themes section of the admin page / dashboard, then click on Apperance > Themese > then click on ‘Preview’ under .

        Hope this helps…

  15. Hi! Thank you for the great lessons.

    I am just wondering why I see also numbers when I copy and paste the code into wordpad.

    Thank you!

  16. Hello,
    Thanks for the easy to follow tutorial. I was just wondering if there was somewhere to get some further instruction on styling it? Among other things I am trying to add a nav bar with rollovers.

  17. Great tutorial so far… One thing I noticed was that in your sample code to copy and paste you have the comments incorrect “”, but they should be “

    Noticed that you reference the code the correct way in the wording on the tutorial but then use the incorrect way in your sample code.

    Great post and many thanks for helping me learn wordpress themes!!!

  18. I don’t know if there is something wrong with the encoding in this page, but the source is badly malformed using Windows with all the recommended software and tools so far.

    This code needs to be re-written with the syntax highlighter plugin or something so the code doesn’t get mangled during cut & paste.

  19. Jacqui,

    wish I could help you more. I have cut and pasted code also when I do not feel like typing or in a hurry and have never had a problem with Ian’s code. Without seeing the specifics, all I can offer is double check everything.

    1. Hi Jim,

      See the bottom of this page, the footer area is copied and pasted from the code on this page. It has one dash instead of two which translates to this format in Windows.

      That is from viewing the page source in Firefox.

      should be not ?

  20. Ok I see what you are talking about but it makes no sense because all of the comments are coded the same way so why sis those at the end read something different!!!!!!!!

  21. I have just located your site while looking for a way to modify my theme. I have run into a problem with the code. I get this error: Fatal error: Call to undefined function get_header()

    I added as a quick test, but already use PHP includes, so I knew that it work work. I have the 6 files in wordpress/wp-content/themes/mytheme

    Any idea what I am doing wrong? If it matters, I am live on a 1and1 hosted site. I need to get another computer to setup my xamp.

  22. Hello,

    I’m getting a Fatal error! :
    Fatal error: Call to undefined function get_header() in C:Xamppxampphtdocswordpresswp-contentthemestestindex.php on line 1


  23. One MASSIVE thing this entire tutorial has glossed over is where to upload?

    How am I uploading? To where? No explanation of this ruins this tutorial for me. I’ve had to give up because this part was completely ignored.

  24. I have a question about indenting the tags etc. in your code.

    (I’m using Coda)

    Does is matter how you indent the tags? I find using tabs is a bit easier for usability. I can better see where a tag opens and closes by scanning down the code.

    I’m quite new to this, I’d love some advice on best practice. I notice you are using spaces in your code.

    P.S. When I copy and paste code from your examples, there are numbers inserted in front of lines. I’m not sure if that’s a Coda thing.

    1. Hello Pete, I’m pretty new to this stuff too, and I’ve found that I do what you do, namely, indent the tags so that I can easily find the start and end tags without the need for commenting the markup.

      The number appeared on Komodo edit too, so I would try rewriting all of the bits we are supposed to copy and paste, otherwise there will be anomalous characters in our code.

  25. How to be a Rockstar WordPress Designer should just have a link to this website, although by the sounds of it, both parties should have a little go at proof reading. Collis Ta’eed perhaps more so.

    I’ve followed your tuts so far and I’m impressed. I only made it to chapter 5 of How to become a Rockstar WordPress designer, and then they lost me due to vague descriptions bad grammar and incomplete descriptions.

    Have you thought about making this into a downloadable book??? I’ll proof read it for you : )

Comments are closed.