Making A WordPress Theme
March 20, 2009 – 5:56 pm
In a blog post about his “Starkers” WordPress theme, designer Elliot Jay Stocks talks about how he used to approach designing for WordPress. He would start with the default theme and remove the bits he didn’t need. That was pretty much how i started off doing it myself – until it struck me i was going about things back to front.
Nowadays, rather than basing a theme around WordPress, i build a static page and then slot WordPress into it. I create the page exactly as i would if i was going to build a static site – starting off with just one single HTML file and the CSS. That way i can get the layout right without having to mess around with any WordPress stuff. Then, once i’ve got it looking right, i slot in the content management system.
The basics of building a WordPress theme are quite simple – once you get the hang of it. If you want to build a theme yourself, or if you want to convert a static web site into a content managed WordPress site, here’s how to go about it. This explains how to create a theme with just two files – index.php and style.css (those names are important) – which is a very rough and ready way to do it. This is aimed at people who do know HTML and CSS, but who don’t know WordPress.
The first thing to understand is that WordPress doesn’t do the layout – you do. WordPress just injects the content into the page you design. The way it does it is with PHP statements that output the relevant part of the content wherever you put them in the page. You don’t need to know anything about PHP to make this work – and if you don’t know PHP, you can think of the PHP statements as sort of magic HTML tags, and not worry too much about the code that’s inside them. WordPress documentation usually refers to them as “template tags”.
Note that these PHP tags start with “<?php
” and end with “?>
” and you must keep the whole thing together as a unit. They mostly produce plain text – and therefore will be formatted only by the HTML tags you wrap round them. However, a few of them do produce HTML – for example the output from both the wp_list_pages and the dynamic_sidebar tags is formatted as an unordered list (<ul>) (they’re mentioned below).
An example of one of WordPress’s “magic” PHP tags is <?php bloginfo('name') ?>
. This displays the name of your blog at whatever position you place the tag in your HTML. You set the name that’s displayed with this tag in the WordPress control panel’s “Settings” menu, on the “General” page – in the field labelled “Blog Title”.There are probably two places where you’ll want to use the <?php bloginfo('name'); ?>
tag – between the <title> and </title> tags in the <header> section, and between the <h1> and </h1> tags in the header part of your <body> section. So you can start off by replacing the text in those places with that tag.
If you care about search engine optimization (and about making things more pleasant for your users), you won’t want to have just the blog name in the <title> tag on every page, so you’ll probably want to put the page title in it as well. To do that, you use the <?php wp_title(); ?>
tag. Now your header title should look something like this:
<title><?php bloginfo('name'); ?> <?php wp_title(); ?></title>
These are some other tags you’ll probably want to use in your <header> section:
<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
<link rel="alternate" type="application/rss+xml" title="<?php bloginfo('name'); ?> RSS Feed" href="<?php bloginfo('rss2_url'); ?>" />
<link rel="alternate" type="application/atom+xml" title="<?php bloginfo('name'); ?> Atom Feed" href="<?php bloginfo('atom_url'); ?>" />
<link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" />
And you’ll definitely want this one
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />
Then, immediately before the </header> tag, you should put this one:
<?php wp_head(); ?>
which allows WordPress to put anything into the header that it needs to put there to make it work properly.
In the <body> section you’ll probably want to use the <h1> page header tags, which i’ve covered above. You may also want a sub-header, or tagline, which you can set in the “Tagline” field of WordPress’s “General Settings” page. To include this in your HTML, you use this tag: <?php bloginfo('description') ?>
Then we come to the site’s main content. You’d probably want to have a div that’ll hold the main content on each page. I’ll call that div “content”. This is what it will probably look like:
<div id="content">
<?php if (have_posts()) : ?><!-- see note 1 -->
<?php while (have_posts()) : the_post(); ?><!-- see note 2 -->
<div <?php post_class() ?> id="post-<?php the_ID(); ?>">
<h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
<span style="font-size:80%";><?php the_time('F jS, Y') ?> by <?php the_author() ?></span>
<div class="entry">
<?php the_content('Read the rest of this entry »'); ?>
</div>
<p class="postmetadata"><?php the_tags('Tags: ', ', ', '<br />'); ?> Posted in <?php the_category(', ') ?> | <?php edit_post_link('Edit', '', ' | '); ?> <?php comments_popup_link('No Comments »', '1 Comment »', '% Comments »'); ?></p>
</div>
<?php endwhile; ?>
<!-- see note 2 -->
<div class="navigation">
<div class="alignleft"><?php next_posts_link('« Older Entries') ?></div>
<div class="alignright"><?php previous_posts_link('Newer Entries »') ?></div>
</div>
<?php else : ?>
<!-- see note 1 -->
<h2 class="center">Not Found</h2>
<p class="center">Sorry, but you are looking for something that isn't here.</p>
<?php get_search_form(); ?>
<?php endif; ?><!-- see note 1 -->
</div><!-- end of content div -->
The above is mostly taken from the WordPress default theme – but i’ve modified it a bit and reformatted it to try and make it work a bit better in this blog post. At first glance it may look like total gobbledgook, but you can just lift the whole thing and paste it into your main page section. The above code will take care of displaying blog posts or static pages – which you can create and organise using WordPress’s content management system.
I’ve inserted html comments referring to note 1 and 2. The tags that these are next two are structurally important and you should be careful not to delete them or move them around.
(1) The “if (have_posts())”, “else”, and “endif” tags wrap around two separate code sections – the part before the “else” displays posts (or pages) and the part after it displays a “Not Found” page if there are no posts or pages. Exactly what posts or pages are displayed by these is controlled by other parts of the WordPress system – but whatever it is that should be displayed on the page will be displayed by the code between the “if” and “else” tags.
(2) The “while (have_posts())” and “endwhile” tags wrap round code that may be used multiple times in one page. This happens on pages that show several blog posts, or teasers from several blog posts. For example, the home page of a blog might show the most recent 5 posts in reverse date order. How many are shown per page is set in the “Blog pages show at most” field on the “Reading Settings” page.
I’m not going to go into too much detail about most of what’s in that block of code – but if you’re reasonably familiar with HTML you should be able to work out more or less what’s going on. However there are one or two things worth pointing out. If you read through it, you’ll notice something that makes the “template tags” different from normal html tags – and that’s that they can be embedded within html tags. For instance, in
<a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"> <?php the_title(); ?></a>
the <?php the_permalink() ?>
tag is inside the <a> tag. When the page is sent to the browser, it gets replaced by the URL that’s needed by the ‘href’ attribute.
This section of code:
<span style="font-size:75%";><?php the_time('F jS, Y') ?> by <?php the_author() ?></span>
puts the date and time that the post was published, along with the author’s name, at the top of the post, underneath the header. Depending on how you want your site, you might want to leave this out altogether – or you may want to style it differently.
This section:
<p class="postmetadata"><?php the_tags('Tags: ', ', ', '<br />'); ?> Posted in <?php the_category(', ') ?> | <?php edit_post_link('Edit', '', ' | '); ?> <?php comments_popup_link('No Comments »', '1 Comment »', '% Comments »'); ?></p>
Displays “meta” data that may be associated with the post or page. It shows tags and the category it’s in. If you don’t want to display tags or categories, you can delete those parts of it. The “edit_post_link” bit produces an “edit post” link that’s only shown to users who are logged on and are authorized to edit that post.
If you follow the logic of the html, you can probably move things around within this main code block fairly easily, or remove them altogether. Get it working properly first, before you start playing around with it though.
Next, you’ll probably want a sidebar with some menu items in it. Of course, you set your sidebar up with HTML and CSS as usual. All you need to put in it for it to work with WordPress is
<?php dynamic_sidebar() ?>
Then you can add “widgets” to it from your WordPress control panel’s “Widgets” page (in the “Appearance” section of the main menu).
To make the sidebar work, though, you must have a file called ‘functions.php’ in your theme directory, containing something like:
<?php
if ( function_exists('register_sidebar') )
register_sidebar(array(
'before_widget' => '<li id="%1$s" class="widget %2$s">',
'after_widget' => '</li>',
'before_title' => '',
'after_title' => '',
));
If you don’t have this file, your sidebar won’t show up in the Widgets menu.
At the bottom of your HTML, immediately before the </body> tag, you should add the <?php wp_footer(); ?>
tag – it allows WordPress to insert anything it needs to insert into the foot of the page, just like the <?php wp_header(); ?>
tag did in the header.
That’s pretty much it for the absolute basics of WordPress theme development. There’s one other thing you may need to know, though, and that’s how to make a horizontal menu (at the top of the page, say). For that you use
<?php wp_list_pages('title_li='); ?>
which will produce an unordered list (<ul>), which you can set to display inline and style appropriately using CSS.
Talking of CSS, i’d recommend using Firefox web browser for developing your WordPress site – and installing the “Web Developer” plugin and the “Aardvark” plugin. They both work differently, but they both allow you to hover the pointer over any part of a web page and see what class or id that HTML element is set to. It’s very handy to be able to do this when you’re working with WordPress layout, because it’s the simplest way to find out what you need to put in your CSS for styling some of the elements. This is particularly true when it comes to styling the sidebar – because the list tags for that are produced by WordPress and the only way to find out what they are is to view the source in your browser, to read the documentation at wordpress.org, or to use Aardvark or the Web Developer plugin to see what the element ids and classes are. The last option’s the easiest!
The final thing that you must do to make your theme work is to have a file called ‘style.css’ and to put the following comment right at the top of it:
/*
Theme Name: Your Theme's Name Here
*/
Without that, it won’t show up in the “Manage Themes” page of your WordPress control panel. (You get to that page by clicking on “Themes” in the “Appearance” section of the main admin menu.) The theme files should be in a subdirectory in wp-content/themes in your WordPress installation. It’s worth putting a screenshot in there as well – called ‘screenshot.png’ and about 300×200 pixels – as that will show on the “Manage Themes” page.
This really has been the absolute rough and ready basics of creating a WordPress theme. I haven’t been building a theme while i’ve been writing it and i can’t guarantee that if you follow exactly what i’ve written here, your theme will work. It’s not intended to tell you everything you need to know, but i hope it’s given you a rough idea of how it all fits together. To do the job properly, you’ll probably want to split your html up into at least 4 separate files – index.php, header.php, footer.php, and sidebar.php. WordPress has its own way of loading those files where they’re needed, and you’ll need to know how to organise that – having a look at the default theme should give you some clues.
Most importantly, there’s a vast amount of very good documentation at http://codex.wordpress.org – you should definitely start by reading the Theme Development page.
Leave a Reply