How to Create a WordPress Theme from Scratch

How to Create a WordPress Theme from Scratch

Tutorial Details
  • Program: WordPress
  • Difficulty: Beginner-Intermediate
  • Completion Time: 1-2 hours

Following on from the recent article on “PSD to HTML”, this tutorial will look at taking a HTML/CSS template and turning it into a functioning WordPress theme. There is so much you can do when creating your own theme we couldn’t nearly cover it all. So, we’re going to look at how themes are structured, creation of the core files and splitting up that index.html file.


Overview – The Structure Of A Theme

The structure of a WordPress theme is fairly simple, I like to start with the CSS file. It details everything about the theme for WordPress to use. You then have index.php – it’s simply the template file you’re using with the PHP template tags included. Included with that is header.php & footer.php, files that are used across the whole site. Now most themes don’t use just four files and that’s because WordPress allows you to use template files to layout different content. There are the defined layout files, such as archives.php and single.php. However you can also create your own, say, if you wanted to make a page that had a totally different layout to the default.

Because this is such a large topic we’re splitting it into a two part series – this part making a simple but functioning theme from a standard HTML & CSS template, and the second part will look at adding more of the advanced features.

I will be working on turning the great template “Typography Paramount” by Six Shooter Media into a simple WordPress theme.


Step 1 - style.css

The style sheet is the defining file of the theme for WordPress. There are a few simple things you need to do. The first is renaming the main (if you have more that one) file to style.css, next you need to add a bit of commenting to the file.

/*
Theme Name: Typography Paramount
Theme URI: http://www.sixshootermedia.com/
Description: An image-less template focusing on Typography.
Author: Sam Parkinson
Author URI: http://xseria.com
Version: 1.0
.
General comments/License Statement if any.
.
*/

The code above is all contained in a comment, so it won’t affect the style definitions. Now I filled it out with a few details, these will be used by WordPress to display the details of the theme to admins. Make sure you add it to the top of the file with no white-spaces before it.

I’ve gone and renamed the style sheet file from the template, it was called 1.css. I have also made a new folder called typography-paramount which will be what I upload to the WordPress theme folder. Put the style sheet in this folder, but not under another directory otherwise it cannot be seen by WordPress.


Step 2 - The Header and Footer

In this step, we’re going to create the two files: header.php and footer.php. Although they are optional both are used in most themes, they’re not exactly hard to use either.

header.php

Starting with the header, create a new file in the theme folder called header.php, then open up index.html from the template and copy the following from it. This will become the header and will be displayed on every page of the site, bear that in mind when making other templates.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>-</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="css/1.css" type="text/css" media="screen,projection" />

</head>

<body>

<div id="wrapper">

	<div id="header">

	<p class="description">

	An imageless template focusing on Typography.

	</p>

	<h1><a href="#">Typography Paramount</a></h1>

	<ul id="nav">

	<li><a href="#">Link Here</a></li>

	<li><a href="#" class="active">Link Here</a></li>

	<li><a href="#">Link Here</a></li>

	<li><a href="#">Link Here</a></li>

	<li><a href="#">Link Here</a></li>

	</ul>

	</div>

We’re now going to add the WordPress template tags to header.php, these tell WordPress where to inject the various content into the theme. Also remember to change that link to the stylesheet.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes() ?>>
<head profile="http://gmpg.org/xfn/11">
<title><?php bloginfo('name'); ?> <?php wp_title(); ?></title>
<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen,projection" />

<?php wp_head(); ?>

</head>

<body>

<div id="wrapper">

	<div id="header">

	<p class="description"><?php bloginfo('description'); ?></p>

	<h1><a href="<?php echo get_option('home'); ?>/"><?php bloginfo('name'); ?></a></h1>

	<ul id="nav">
	<?php wp_list_pages('sort_column=menu_order&title_li='); ?>
	</ul>

	</div>

There’s quite a lot that’s been added but it’s all fairly simple when you look through it. All the tags above are well documented in the WordPress Codex. I’m just going to go through what each of the functions do.

language_attributes() – Prints the language type for the <html>
tag.
bloginfo() – Used to print information about the site, the parameters
are available on the Codex, ‘name’ returns the title of the blog.
wp_title() – Simply returns the title of the page.
wp_head() – Prints the javascript links and other header stuff.
get_option() – Retrieves a value from the options database.
wp_list_pages() – Lists links to the site’s pages, the parameters sort
the pages correctly and also stop WordPress from printing a default title.

footer.php

Create the file footer.php and copy everything in the template from <div id="footer"> down-wards and shove it in the new file. A dynamic footer that displays the correct year, site title and a feed link is common place in themes, so lets add one.

<div id="footer">

	<!-- Please leave this line intact -->
	<p>Template design by <a href="http://www.sixshootermedia.com">Six Shooter Media</a><br />
	<!-- you can delete below here -->

	© <?php the_time('Y'); ?> <?php bloginfo('name'); ?><br />
	<a href="<?php bloginfo('rss2_url'); ?>">Grab the feed</a></p>

</div>

</div>

< ?php wp_footer(); ?>

</body>
</html>

I’ve gone and changed the footer to display the copyright icon, followed by the current year (<?php the_time('Y'); ?>) and the site’s name (<?php bloginfo('name'); ?>) then on a new line put a link to the rss feed (<?php bloginfo('rss2_url'); ?>).

wp_footer() is what WordPress uses to add things to the bottom of the
site, more often that not used by plugins to add things like site tracking code.


Step 3 - The Core File

We’re now going to create index.php

index.php

This is one of the two required files for a WordPress theme (the other being style.css), so lets get started. Create the file and put it along with the rest, then add to it the following.

<?php get_header(); ?>

<?php get_footer(); ?>

This simply tells WordPress where to include the header.php and footer.php files. Because this is a two part series we’re going to include the creation of the sidebar in the next article. You can either chose to leave it’s div in as static html or just leave it out which is what I will do. Add the following between the previous two tags.

<div id="content">

	<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

	<h2><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h2>

	<?php the_content(); ?>

	<p><?php the_time('F j, Y'); ?> at <?php the_time('g:i a'); ?> | <?php the_category(', '); ?> | <?php comments_number('No comment', '1 comment', '% comments'); ?></p>

	<?php endwhile; else: ?>

	<h2>Woops...</h2>

	<p>Sorry, no posts we're found.</p>

	<?php endif; ?>

	<p align="center"><?php posts_nav_link(); ?></p>

</div>

This is what WordPress call the WordPress Loop. The first line of PHP starts this loop, endwhile is the end of it. WordPress fills out the loop for each article on the site, and if there isn’t any it displays that “Woops…” content. I’ve also added a navigation link that will place link’s to more articles, so visitors can take a look at older content without using the archive.

In the next article we will write up single.php, this would be what is displayed if a visitor clicks on the title of a post. It will include the commenting system, unlike index.php.


Review – Does it Work?

So we now have four files in out theme, assuming that you didn’t forget to update you index.php file (doh!) it should work as a simple but functional theme.

Test it out in that new theme previewer that been put in the latest WordPress, after looking around there only seems to be an issue with long titles, easily fixed by adding the following to #content h2 in the style sheet.

line-height: 30px;

Continue to Part 2.

Add Comment

Discussion 236 Comments

Comment Page 4 of 5 1 2 3 4 5
  1. Nice tutorial.. b^^d
    now I can create my own wordpress themes..
    thanks :)

  2. Thiago says:

    What program are you using to update the css & php files shown in the screenshots?

  3. HI, this is a very rich tutorial info. i am planning to make my own theme now. thanks for the inspiration.

  4. Hi There,

    thanks for this very educative post. i’ll use it on my web devs.
    thanks again.

  5. chris says:

    Many pictures in tutorial are missing, o not? is possible my navigator is wrong? I’m sorry my english

  6. MARS says:

    what happened to the CREATIF full version of this tut it was up yesterday but it’s gone now, it was great and I could really use it right now.

    Thanks

  7. vaanres says:

    excuse me , i can not download source code , please fix it !

  8. levi says:

    links to demo are broken….

  9. newbie says:

    Will you take a look on the problem with the demo link and the pictures?
    It’s kinda difficult to do this tut without the pictures or…?

  10. Razvan says:

    The SOURCE and DEMO links do NOT WORK!

  11. tatut says:

    Link demo please ???

  12. Jogos Gratis says:

    All the links and images are broken. what is going on?

  13. mark says:

    nice work, very informative. this would help me.

  14. wow says:

    Wow what the fuck fix your files this post is useless.

  15. Stephen says:

    Missing images…

  16. moni says:

    link is broken. pls fix.

  17. dan says:

    hey,
    reasonable tutorial,however i have seen many premium themes where the designer has included their initials etc into the code,how would i implement the same?

    example:

    <?php } elseif(DYN_OUTSKIN==”three” && $DYN_outskin!=”one”) { ?>

  18. Furqan Aziz says:

    Very Nice Work.

  19. Rudy Pohl says:

    Hi Sam:

    Great turorial. I’m really looking forward to part 2 and then getting started on my own theme.

    Thanks for this….

  20. leonku says:

    thanks man alot. i had my design and was stuck . now am working on this http://www.rea.or.ug

  21. I truly appreciate all of the time and attention you have put into this tutorial however with out the working links I am at a loss.

  22. james says:

    I have a few questions regarding this tut.

    I’m a complete newb to wordpress.

    I followed everything and it works awesome,but
    what exactly do you have to do to create a content div that expands along with the blog? other than having to add a overflow in the css that adds scrollbars.I think i am missing something.Anyhow,if anyone would be willing to help me out and explain this to me,I would be completely appreciative.

    Thank you so much.

    -James

  23. Great post. I had hit the wall on my WordPress revision and thanks to you I am over the hump!

  24. Moble Rates says:

    its very helpful but i m facing some problems in sidebar i make 2 side bar but its not working

  25. Very Useful Post ,

    can you please make more graphical wordpress theme ?

  26. Joe Joiner says:

    Great tutorial. Perfect for newbies to WordPress theme development :D

  27. I just created my first theme! I had about 10 errors because I typed it all out myself, but I think that’s the best way for me to learn. I got them fixed though and my theme is up! Thanks :-D

  28. Francis says:

    This is a really nice tutorial! I’ve bookmarked this post and Thanks! ^ ^ All the long I was using free wordpress themes from http://www.magetemplates.com , guess is time for me to really hands on.

  29. John says:

    Your HEADER.PHP directions are really confusing at the beginning of this tutorial.

    • achimmer says:

      I agree with John, the Header.php instructions are not quite clear. What do you mean we have to change the URL to the stylesheet? I didn’t think we had to change any url (ex: url to CSS stylesheet on all wordpress themse is “stylesheet_url”). What excactly do you mean? Why are you using this index.html page anyway? Could you explain how to correctly organize our wordpress file directories at the begining? Because otherwise none of your php SSI’s are going to work.

  30. This is a great tutorial! Definitely what I was look for :)

  31. I really like the theme tutorial, it gave me some courage to make my own blog for my companies website to integrate into our website completely. I suck at wordpress as a coder but this helped me come up with the basics to help make custom templates for others to use and run off of.

    Keep up the tutorials and hope to see more wordpress tutorials like this one to help with designers problems and such in php.

  32. thanks this was very helpful for me

  33. Bob says:

    At first i directly modified a theme that i have downloaded from wordpress which is not the best thing to do for a newbie like me. This is a good post. Thank you

  34. Magnus says:

    Great tutorial!

    However, mine is not working as intended. The CSS stylesheet seems to be missing. I know it’s physically there, in it’s folder. The code I am using should be identical to the one in the tutorial.

    <link rel="stylesheet" href="” type=”text/css” media=”screen,projection” />

    Still, it looks like my stylesheet doesn’t load. Please help!

    • Char says:

      Magnus, you need a location of the style sheet after href=”

      For example, if the style sheet is in the same folder, and is called “styles.css”, then the code would be href=”styles.css”

  35. xplicit says:

    Thanks for this tutorial.

    Now I can create my own WordPress Template.

  36. Tim says:

    Great tutorial guys

  37. colin says:

    Good post. I study one thing more difficult on completely different blogs everyday. It’s going to at all times be stimulating to learn content material from different writers and observe somewhat one thing from their store. Iíd prefer to make use of some with the content on my weblog whether or not you donít mind. Natually Iíll provide you with a hyperlink in your net blog. Thanks for sharing.

  38. Aminul Islam says:

    Owao! Its Very Helpful WordPress Theme Making Tutorial For Me. Thank you Very Much!

  39. Hello! I simply want to give an enormous thumbs up for the good info you could have here on this post. I will probably be coming again to your blog for extra soon.

  40. strongzz This is very interesting, You’re a very skilled blogger. I’ve joined your rss feed and look forward to seeking more of your wonderful post. Also, I’ve shared your site in my social networks!

  41. NSDL Pan says:

    i want attach xternal css how can i do this in word press theme ?

  42. Mark Hallam says:

    How do you make multi-columns that show posts based on categories on the frontpage? Thanks.

  43. Cupidf007 says:

    It was awesome !! Is there any way to add login on the front page coz I am a newbie to this wordpress stuff.

  44. Starfall says:

    This is an amazing tutorial, I am willing to read and learn more. Hope you will view more tutorials on making different kinds of themes. From simple themes to complex. Great Job!

  45. I just created my first theme! I had about 10 errors because I typed it all out myself, but I think that’s the best way for me to learn. I got them fixed though and my theme is up! Thanks :-D

  46. Ian says:

    It seems in step two, we create the header.php and then replace it’s contents for the nav menu with this

    So the end result has no nav links but in the screen shot at the end it looks like you left all those links in so now I’m confused as to where the code was supposed to go.

  47. Ian says:

    OK sorry I was confused but now I see when I create a new page it gets automatically added. Cool thing is this is still working on version 3.3 in 2011 because it’s so basic.

    I couldn’t reply to my original question because I guess nettuts brakes with so many comments. It won’t load the comments so I can see mine to put a reply on it.

  48. SostsTech says:

    Waow. Great deal here! I am new to blogging and i found the latest information here on your blog. Please let me know in your recent posts that how to add slider / featured posts widget above the posts in WordPress blog. Thanks in advance.

  49. nono 8800 says:

    It’s actually a cool and useful piece of info. I am satisfied that you simply shared this useful info with us. Please keep us informed like this. Thank you for sharing.

Comment Page 4 of 5 1 2 3 4 5

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.