How to Build a Custom WordPress Theme from Scratch

How to Build a Custom WordPress Theme from Scratch

If you’re confident with your CSS and HTML, it’s not hard at all to step up to the challenge of building a custom WordPress theme. This overview shows the process of how my latest custom WordPress theme from scratch was built from design concept through to completed theme. See how the static design is split up into the various WordPress theme files, and discover how the simple PHP snippets can add that dynamic functionality of a blog.

Anatomy of a WordPress theme

Before getting stuck into the build process, it's important to know how WordPress themes work. If you've looked at any prebuilt theme, you'll notice that it's all contained in a folder, and there's around 12 core files. Some themes, including the Default WordPress theme, include more files which allow extra customisation, but aren't mandatory additions. Here's an overview of the main files you'll be working with:

  • header.php – Contains everything you'd want to appear at the top of your site.
  • index.php – The core file that loads your theme, also acts as the homepage (unless you set your blog to display a static page).
  • sidebar.php – Contains everything you'd want to appear in a sidebar.
  • footer.php – Contains everything you'd want to appear at the bottom of your site.
  • archive.php – The template file used when viewing categories, dates, posts by author, etc.
  • single.php – The template file that's used when viewing an individual post.
  • comments.php – Called at the bottom of the single.php file to enable the comments section.
  • page.php – Similar to single.php, but used for WordPress pages.
  • search.php – The template file used to display search results.
  • 404.php – The template file that displays when a 404 error occurs.
  • style.css – All the styling for your theme goes here.
  • functions.php – A file that can be used to configure the WordPress core, without editing core files.

Each of these files then contains a series of PHP template tags. These tags tell WordPress where to insert the dynamic content. A good example is the <?php the_title(); ?> tag, which pulls in the post title and displays it in your theme:

There's stacks of template tags available, and more often than not there will be one that does exactly what you want – It's just a case of finding it in the WordPress Codex. I've seen many themes that include some complicated PHP coding to achieve a function that's already available as a simple template tag, so remember to browse the WordPress Codex whenever you're stuck!

Anatomy of a WordPress theme

Seeing as a WordPress Theme is basically made up of HTML and CSS, but with a few extra PHP tags inserted here and there, it's important to build your website concept as you would a good old static site. I tend to build the complete page with dummy content, then do my browser testing before starting work on the theme. Here's an overview of my HTML code:

Building the WordPress theme

Now the actual design is taking shape in code form, it's time to start converting the static HTML and CSS into a WordPress theme. Begin by creating a folder for your theme and creating the php files above (header.php, etc). Sometimes it's easier to download the WordPress application, then duplicate the Default theme, and delete out any extra fluff that comes with it. Either way, you'll want all your PHP files in place, and all your images and Javascript files copied into your theme folder.

Configuring the stylesheet

All the details of a WordPress theme are contained within the stylesheet.

Also remember to ensure that the paths to any background images are correct in your CSS properties.

Populating the header

Open up your header.php file, and paste in the head section from your concept HTML file. Then we need to go in and replace certain elements with the correct WordPress template tags to ensure it all works correctly. First we can strip out the title and insert some WordPress template tags. bsg_title(); will display the title of the page, which is followed by bloginfo('name'), which will place the blog's name (set in the admin panel).

bloginfo('stylesheet_url'); is the snippet used to call the stylesheet. This replaces the manual path we created in the concept. Other files, such as Javascript can be called using the bloginfo('template_url'); tag. This renders the path to the theme folder in HTML.

If you would like your theme to make use of threaded comments, a snippet can be placed that will call the relevant Javascript files from the WordPress core. Then to before the closing </head> tag, add bsg_head();, this is where any additional head elements are placed by WordPress plugins etc.

Building the index

The next step is to flesh out the main body of the website. Open up the index.php file and paste in the main bulk of the concept HTML.

This is where all the meaty stuff begins! At the top we have the get_header(); and get_sidebar(); tags, these call the header.php and sidebar.php files and render the content according to where the tags appear. The WordPress loop is then used to check for content, if there's content available it's rendered onto the page. Within the loop we have various tags that display the post information, such as the_title();, and the_permalink();. These are wrapped in the usual HTML elements according to their purpose, so the permalink is wrapped in an anchor tag and the title in a header 2 tag.

the_post_thumbnail(); is an optional addition, but this code simply makes use of the new post thumbnail feature in WordPress 2.9. Below this is where we want all the article content to appear, and it's simply inserted with the the_content(''); tag.

In the meta section, there's various tags that can display specific information about the post, such as the time it was posted, the category it was posted in and how many comments it has. All of these can be called using a template tag such as the_time('F jS, Y');, each one also has certain parameters to further tailor the tag to suit. For instance the time can be changed to display in various formats. This is where the WordPress Codex comes in handy, to double check any parameter options you have.

Skipping down a little, the loop then displays an else tag, which will display if no posts are found, and the loop is finally closed with an endif. At the bottom we can use get_footer(); to call the rest of the page, which resides in the footer.php file.

Filling out the sidebar

The sidebar in my design is where the list of pages and categories are held. The sidebar.php file was called from the index using the get_sidebar(); tag, so anything within this sidebar.php file is inserted into the theme in the right place.

There's only three elements in my sidebar; the logo, the pages list and the categories list. The logo is wrapped in a h1 tag and uses the tags echo get_option('home'); and bloginfo('name'); to render the URL of the blog and the blog name in the appropriate places. The pages list is simply added using bsg_list_pages('title_li=' );, where the parameter stops the usual ‘Pages' title from being added. The list of categories is also pretty similar, bsg_list_categories(); is used along with various parameters to customise the tag, such as show_count=0 to stop WordPress showing how many posts appear in each category, hide_empty=0 to show the category even if it doesn't have any posts, and exclude=1 to exclude the category with the ID of 1, which is the Uncategorized category.

Rounding off the footer

The footer.php file is probably the most simple file for this theme. The only thing that goes in here is the bsg_footer(); tag just before the </body>, so that any extra info can be inserted in the correct place. In your theme you might display a list of popular posts, latest comments or a list of archives. All of these can be done using specific WordPress
template tags.

Creating the archive

The archive.php file is used to display a list of posts whenever they're viewed by category, by author, by tag etc. It's basically the same as the index file, but with the addition of a tag at the very top that renders a useful page title, so the user knows where they are. ‘Browsing the Articles category' for instance.

Constructing the page and single view

WordPress is made up of posts and pages. Posts use the single.php template file, whereas pages use the page.php template file. They're pretty much the same, apart from that you tend to include the comments_template(); tag for posts, and not for pages.

Configuring the comments template

I usually copy the comments template from the Default theme, then make my changes because it includes some important lines of WordPress code.

Once you have a comments file created, the same file can be used on pretty much all your future WordPress theme projects. The hard part is finding the CSS hooks to style up your comments. This is when the Firebug plugin for Firefox comes in handy. Otherwise, the comments file just has a few parameter options here and there that you might want to tweak. One that springs to mind is the avatar_size parameter, which tells WordPress how large to make the user's Gravatar image.

Finishing off the search and 404

This pretty much just leaves the search feature, which is basically a copy of the archive.php file. A handy additions might be the line Search results for <?php the_search_query() ?>, which will display the user's search term as a title. As for the 404 page, this is where your creativity comes into play. This template can be configured to display whatever error information you like, just remember to include the usual get_header();, get_footer(); tags where necessary

Written by
Suresh Patel
Join the discussion


Let’s get social

Web design blog for professionals with topics focusing on useful design techniques, design best practices and design inspiration. Subscribe for updates!



Following our blog is a great way to make sure that you are up to date on the latest and greatest Freebies and WordPress news.