Note: This is an old post, written for a version of wordpress long forgotten, and while it all should still work there may be a few functions that have been depreciated. Its still an ok introduction though.

You can download the files used in this tutorial here.

Rhys suggested I write some design tutorials – so thats just what I’m going to do. I’m going to teach you how to design your blog, graphics, CSS, HTML and all! This is effectively a rewrite of my previous tutorial on how to customise WordPress, only in much greater detail.

This article assumes you have basic skills when it comes to web design. No tiny fonts and clashing colours here please! You’ll need to have wordpress installed. Please also keep this page open, its the most useful thing when making themes!

Some other useful pages are Using Themes, Theme Development and Templates.

Navigation

I’m working with wordpress here but the concepts and the coding remain the same for all platforms, the only things that differ are the template tags, but we’ll get onto those later.

Initial Design

First you need to know what you want your blog to look like. I usually do a mock up in Photoshop, its easy to modify and expand upon. (If you don’t have Photoshop you can use paint shop pro or gimp)

Open Photoshop and Create a new document, I usually make mine 1000×700. Because this is a blog I’m going to go for a simple two column layout with a header on the top.

Now I have a rough idea of what I want my site to look like, I’m going to start coding it.

First though I need to explain a bit about the structure of the site. I find it really helps to visualise CSS.

This is effectively the stylesheet I’ll be using, in graphical form. A great way to understand CSS layouts is to mess around with the CSS Creator, Its a great starting point for any website.

A 3 Column layout uses the same ‘container’ principal.

Login to your FTP and navigate to your wordpress installation directory, go to wp-content/themes and create a new folder, call it whatever you want. This is the folder where we will start building your site.

Firstly make a file called style.css and add the following to it.

	/*
	Theme Name: femgeek.co.uk
	Theme URI: http://www.femgeek.co.uk
	Description: femgeek theme tutorial
	Author: Hannah
	Author URI: http://www.femgeek.co.uk
	*/

This is needed in order for you to be able to select the working theme in wp admin.

The first section of the theme we’re going to work on is the main page, this is the section people see first.

header.php

This is ‘included’ in all pages using a php include. It helps to maintain consistency throughout the site. Everything in this file will be included in the site – this can be very useful.

Create a new file in your folder, call it header.php. Add this to your header.php page.

	<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
	   "http://www.w3.org/TR/html4/strict.dtd">

	<html lang="en">
	<head>

This is called a doctype, it tells a validator which type of markup your using. In order to have valid markup this must be present, you can find out more about doctypes here

   <title><?php wp_title(); ?> <?php bloginfo('name'); ?></title>

This is our first example of a template tag. This is wordpress’s way of calling up a set of variables you have defined in the various options in the wordpress admin.

	<!-- Meta Data -->
	   <meta http-equiv="Content-Type" content="text/html; charset=<?php bloginfo('charset'); ?>" />
	   <meta name="generator" content="WordPress <?php bloginfo('version'); ?>" />
	   <meta name="description" content="This is a tutorial on how to create a wordpress theme" />
	  <meta name="keywords" content="keywords, that, descibe, your, blog" />

Meta tags, Some people say their useless and that search engines ignore them, but I think their vital. They give search engines data to index your site.

	<!-- CSS -->
	<link type="text/css" rel="stylesheet" href="<?php bloginfo('template_url'); ?>/style.css" />

CSS, cascading style sheets should be the only thing applying style to your website. Without CSS a site should have a white background, black text and horrible blue links in a solid block of text.

	<!-- RSS Feeds -->
	   <link rel="alternate" type="application/rss+xml" title="RSS" href="<?php bloginfo('rss_url'); ?>" />

	<!-- Ping URL -->
	   <link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" />

	<!-- Get Archives Tag-->
	   <?php wp_get_archives('type=monthly&format=link'); ?>

	<!-- Call to various plugin data -->
	   <?php wp_head(); ?>

	</head>

The rest of the information in the head tag, allows browsers to auto detect your RSS feed, your ping URL, archives and a little tag some plugins use.

Everything after this is setting up the content to be formatted with CSS.

<body>

<!--main width definition-->
<div id="container" >

<div id="Header">
<div class="name"><a href="<?php bloginfo('blog_url'); ?>"><?php bloginfo('name'); ?></a></div>
<div class="description"><?php bloginfo('description'); ?></div>
</div>	

<!--right container-->
<div id="main" >

As a general rule id is used for positioning and class is used within id, to customise text and links, etc.

So here is our header.php, save it to your theme folder.

	<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
	   "http://www.w3.org/TR/html4/strict.dtd">

	<html lang="en">
	<head>
	   <title><?php wp_title(); ?> <?php bloginfo('name'); ?></title>

	<!-- Meta Data -->
	   <meta http-equiv="Content-Type" content="text/html; charset=<?php bloginfo('charset'); ?>" />
	   <meta name="generator" content="WordPress <?php bloginfo('version'); ?>" />
	   <meta name="description" content="This is a tutorial on how to create a wordpress theme" />
	  <meta name="keywords" content="keywords, that, descibe, your, blog" />

	<!-- CSS -->
	<link type="text/css" rel="stylesheet" href="<?php bloginfo('template_url'); ?>/style.css" />

	<!-- RSS Feeds -->
	   <link rel="alternate" type="application/rss+xml" title="RSS" href="<?php bloginfo('rss_url'); ?>" />

	<!-- Ping URL -->
	   <link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" />

	<!-- Get Archives Tag-->
	   <?php wp_get_archives('type=monthly&format=link'); ?>

	<!-- Call to various plugin data -->
	   <?php wp_head(); ?>

	</head>

	<body>

	<!--main width definition-->
	<div id="container" >

	<div id="Header">
	<div class="name"><a href="<?php bloginfo('blog_url'); ?>"><?php bloginfo('name'); ?></a></div>
	<div class="description"><?php bloginfo('description'); ?></div>
	</div>	

	<!--right container-->
	<div id="main" >
index.php

This is a bog standard index.php page, the main purpose of the index page is to display your posts. You’ll notice <?php get_header(); ?> this calls your header.php page and displays it as if it was there all along.

I started some div tags in the header, the content of the div is in the index.php page and the div tag is closed in the footer.php file. This is particularly helpful with the other pages in the template, single.php, page.php etc.

index.php is where ‘the loop’ comes in. Its just a fancy way of showing more than one post.

Again you’ll want to refer to The Template Tags for things you can add to your index page, I’ve included the most common ones, date, category, edit this link and comments.

	<?php get_header(); ?>

	<!--this is the loop-->
	<?php if (have_posts()) : while (have_posts()) : the_post(); ?>

	<div class="postHead">

	<div class="title">
	<h2 id="post-<?php the_ID(); ?>">
	<a class="title" href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(''); ?>"><?php the_title(''); ?></a></h2>
	</div> <!--end title-->

	<div class="postinfo">
	Posted in <em><?php the_category(', ') ?></em> on <?php the_date(); ?>
	<?php comments_popup_link(__('Leave a Comment'), __('1 Comment'), __('% Comments')); ?>
	</div> <!--end postinfo-->

	</div> <!--end postHead-->

	<!--call to the posts-->
	<div class="post"><?php the_content('click to read more &raquo;'); ?></div>

	<?php comments_template(); // Get wp-comments.php template ?>

	<?php endwhile; else: ?> <!--ends the loop-->

	<!--this is displayed if you have no posts-->
	<p><?php _e('Sorry, no posts matched your criteria.'); ?></p>

	<?php endif; ?> <!--ends the loop-->

	<!--navigation between posts-->
	<div class="navigation">
	<?php next_posts_link('&laquo; Previous Entries') ?><?php previous_posts_link('Next Entries &raquo;') ?>
	</div>

	<?php get_footer(); ?>
footer.php

In the footer.php file we see another include, this time to sidebar.php. A footer is included for disclaimers etc and the container div is closed.

	</div> <!--end main-->

	<!--call to sidebar-->
	<?php get_sidebar(); ?>

	<div id="footer">
	This is a <a href="http://www.femgeek.co.uk">femgeek.co.uk</a> tutorial.
	</div>

	</div>
	<!--end container-->

	</body>
	</html>
sidebar.php

This is where you can include lots of exciting Template Tags!

Start off your sidebar.php with the following.

	<div id="sidebar">

	</div>

From here you can add what you do and don’t need.

Firstly, how about a list of your pages?

	<ul>
	<?php wp_list_pages('title_li='); ?>
	</ul>

Your visitors are going to want to search your site, so include a search form too!

<?php include (TEMPLATEPATH . '/searchform.php'); ?>

You’ll need to create a new file, searchform.php and place this in it.

	<form method="get" id="searchform" action="<?php bloginfo('home'); ?>/">
	<input type="text" name="s" class="search" value="" />
	<input type="submit" id="searchsubmit" value="Search" />
	</form>

A list of Archives is useful too.

This will display a list of the last 5 months

	<ul>
	<?php wp_get_archives('type=monthly&limit=5&before=<li>&after=</li>'); ?>
	</ul>

or a list of your last 5 posts

	<ul>
	<?php wp_get_archives('type=postbypost&limit=5&before=<li>&after=</li>'); ?>
	</ul>

You might also want to display a list of Categories

	<ul>
	<?php wp_list_categories('title_li='); ?>
	</ul>

and finally, some links.

	<ul>
	<?php get_linksbyname('Categoryname', '<li>', '</li>', '', FALSE,
	'name', FALSE); ?>
	</ul>

You can also display the calendar.

<?php get_calendar(); ?>

The sidebar is where most plugin functions will be placed.

This is what my sidebar.php looks like now.

	<div id="sidebar">

	<h1>Pages</h1>
	<ul>
	<?php wp_list_pages('title_li='); ?>
	</ul>

	<h1>Search</h1>
	<?php include (TEMPLATEPATH . '/searchform.php'); ?>

	<h1>Latest Posts</h1>
	<ul>
	<?php wp_get_archives('type=postbypost&limit=5&before=<li>&after=</li>'); ?>
	</ul>

	<h1>Archives</h1>
	<ul>
	<?php wp_get_archives('type=monthly&limit=5&before=<li>&after=</li>'); ?>
	</ul>

	<h1>Categories</h1>
	<ul>
	<?php wp_list_categories('title_li='); ?>
	</ul>

	<h1>Links</h1>
	<ul>
	<?php get_linksbyname('Sites', '<li>', '</li>', '', FALSE,
	'name', FALSE); ?>
	</ul>

	<h1>Calendar</h1>
	<?php get_calendar(); ?>

	</div>

Thats your main bit done!

Obviously when you view your site it’ll be a complete and utter mess but we’ve still got more pages to do before we start styling it!

comments.php

comments.php is one of the hardest files to get to grips with! I’ve edited this one and commented it as best I can, I wouldn’t worry hugely about customising it.

	<!--If theres comments - display them like this-->
	<?php if ( $comments ) : ?>
		<div class="singolocommento">
			<ol class="commentlist">
				<?php foreach ($comments as $comment) : ?>
					<div class="bubble">

	<li class="$oddcomment" id="comment-<?php comment_ID() ?>">
	<cite>
	<strong>
	<!--comment author and link to their site-->
	<a class="author" href="<?php comment_author_url(); ?>"><?php comment_author(); ?></a>
	</strong>
	<!--comment info-->
	<?php comment_date() ?>, <?php comment_time() ?> <?php edit_comment_link('edit', '', ''); ?>
	<br />
	</cite>
	<div class="commentText"><?php comment_text() ?></div>
	</li>
					</div>
				<?php endforeach; ?>
			</ol>
		</div> <!--end singleolocommento-->

	<!--this is what happens if theirs no comments-->
	<?php else : // If there are no comments yet ?>
	<p><?php _e('No comments yet.'); ?></p>

	<?php endif; ?>

	<!--start comment form-->
	<div class="commentEntry">
	<div class="title"><?php comments_number(__('No Comments'), __('1 Comment'), __('% Comments')); ?>

	<!--this is displayed if comments are allowed-->
	<?php if ( comments_open() ) : ?>
		<a href="#postcomment" title="<?php _e("Leave a Comment.."); ?>">&raquo;</a>
	<?php endif; ?>

	</div><!--end commentEntry-->

	<div class="postinfo">
	<br />
	<?php comments_rss_link(__('<abbr title="Really Simple Syndication">RSS</abbr> feed for comments on this post.<br />')); ?>

	<!--display this if pings are open-->
	<?php if ( pings_open() ) : ?>
	<a href="<?php trackback_url() ?>" rel="trackback"><?php _e('TrackBack <abbr title="Uniform Resource Identifier">URI</abbr>'); ?></a>
	<?php endif; ?>

	</div><!--end postinfo-->

	<?php if ( comments_open() ) : ?>

	<!--if you must be logged in to comment-->
	<?php if ( get_option('comment_registration') && !$user_ID ) : ?>

	<p>You must be <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?redirect_to=<?php the_permalink(); ?>">logged in</a> to post a comment.</p>

	<?php else : ?>

	<!--if anyone can comment-->
	<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">

	<!--get registered users info-->
	<?php if ( $user_ID ) : ?>

	<p>Logged in as
	<a href="<?php echo get_option('siteurl'); ?>/wp-admin/profile.php"><?php echo $user_identity; ?></a>.
	<a href="<?php echo get_option('siteurl'); ?>/wp-login.php?action=logout" title="<?php _e('Log out of this account') ?>">Logout ?</a></p>

	<!--If not Registered enter your info here-->
	<?php else : ?>
	<table border="0" width="70%" class="commentTable">
	<tr>
	<td valign="top">
	<input type="text" name="author" id="author" value="Name" size="22" tabindex="1"/>
	<br />
	<input type="text" name="email" id="email" value="email" size="22" tabindex="2"/>
	<br />
	<input type="text" name="url" id="url" value="URL" size="22" tabindex="3"/>
	<?php endif; ?>

	<!--comments textarea is shown to everyone-->
	<textarea name="comment" id="comment" cols="70%" rows="20" tabindex="4" value="your comment?"></textarea>
	<br />
	<input name="submit" type="submit" id="submit" tabindex="5" value="Submit Comment" />
	<input type="hidden" name="comment_post_ID" value="<?php echo $id; ?>" />
	<input type="hidden" name="comment_reply_ID" id="comment_reply_ID" value="0" />
	<?php do_action('comment_form', $post->ID); ?>
	</form>
	</td>
	</tr>
	</table>
	<p><small>
	<strong>XHTML:</strong> You may use these tags: <?php echo allowed_tags(); ?>
	</small>
	</p>

	<?php endif; // If registration required and not logged in ?>

	<!--this is what is displayed when comments are closed-->
	<?php else : // Comments are closed ?>
	<p><?php _e('Sorry, the comment form is closed at this time.'); ?></p>
	<?php endif; ?>

	</div> <!--end commentEntry-->
page.php

pages.php is the template which you want your pages to follow. Read more about pages here.

This is a simple page template.

	<?php get_header(); ?>

	<!--the loop-->
	<?php if (have_posts()) : ?>
	<?php while (have_posts()) : the_post(); ?>

	<div class="title"><?php the_title(''); ?></div>

	<?php the_content(); ?>

	<?php edit_post_link('Edit this entry.', '', ''); ?>

	<?php endwhile; ?>

	<?php endif; ?>

	<?php get_footer(); ?>

You can also create custom page templates, for specific requirements by adding the following to the top of a new .php file. You can then select the template name from the drop down ‘page template’ option on the ‘write page’ page. (phew!)

	<?php
	/*
	Template Name: Template Name
	*/
	?>
Styling

wow, we’ve made a wordpress theme! Well, almost – now we need to style it with the style.css file!

We’ve already created the beginnings of the style.css page, these variables are needed in order for you to be able to select the working theme in wp admin.

Use this CSS reference for help.

We’ll start by positioning all the elements. I showed in my diagram earlier.

	/*positioning*/

	#container {
	-moz-border-radius: 20px 20px 20px 20px;
	width: 80%;
	margin-left:auto;
	margin-right:auto;
	position: relative;
	background-color: #212121;
	padding: 10px;
	}

	#Header {
	-moz-border-radius: 20px 20px 20px 20px;
	background-image: url(headerurl) !important;
	background-repeat: no-repeat;
	background-position: bottom left;
	background-color: #212121;
	width: 100%;
	height: 160px;
	text-align: center;
	}

	#main {
	float: right;
	display:inline;
	position: relative;
	width: 70%;
	}

	#sidebar {
	float: left;
	display:inline;
	position: relative;
	width: 30%;
	}

	#footer
	{
	clear:both;
	text-align: center;
	width: 100%;
	}

I’ve included some snazzy CSS3 for rounded corners in this Read more here

Once I’ve positioned everything its time to work on the class divs.

The final stylesheet for this particular theme will look something like this.

	/*
	Theme Name: femgeek.co.uk
	Theme URI: http://www.femgeek.co.uk
	Description: femgeek.co.uk theme tutorial
	Author: Hannah
	Author URI: http://www.femgeek.co.uk
	*/

	/*positioning*/

	html, body
	{
	background-color: #282828;
	margin-top: 10px;
	margin-bottom: 10px;
	font-family: tahoma, verdana, sans-serif;
	font-size: 12px;
	color: #555;
	line-height: 18pt;
	}

	/*positioning*/

	#container {
	-moz-border-radius: 20px 20px 20px 20px;
	width: 80%;
	margin-left:auto;
	margin-right:auto;
	position: relative;
	background-color: #212121;
	padding: 10px;
	}

	#Header {
	-moz-border-radius: 20px 20px 20px 20px;
	background-image: url(header.gif) !important;
	background-repeat: no-repeat;
	background-position: bottom left;
	background-color: #212121;
	width: 100%;
	height: 160px;
	text-align: center;
	}

	#Header .name {
	color: #cefa48;
	font-family: "century gothic", sans-serif;
	font-size: 30px;
	font-weight: lighter;
	letter-spacing: 20px;
	padding-top: 80px;
	}

	#Header .name a {
	color: #cefa48;
	}

	#Header .description {
	color: #ccc;
	text-transform: uppercase;
	font-size: 10px;
	font-weight: lighter;
	}

	#main {
	float: right;
	display:inline;
	position: relative;
	width: 70%;
	}

	#sidebar {
	float: left;
	display:inline;
	position: relative;
	width: 30%;
	}

	#footer
	{
	clear:both;
	text-align: center;
	width: 100%;
	}

	/*posts*/
	.postHead {
	-moz-border-radius: 10px 10px 10px 10px;
	background-color: #282828;
	padding-left: 10px;
	}

	h2 a.title, h2 .title, .title, .wrap h2, .catlink, #newlink h2
	{
	padding-left: 0px;
	font-family: "century gothic", arial, georgia, sans-serif;
	font-size: 20px;
	color: #cefa48;
	text-align: left;
	font-weight: lighter;
	}

	.postinfo
	{
	font-size: 11px;
	font-family: "arial", "century gothic", sans-serif;
	font-weight: lighter;
	text-align: left;
	padding-left: 0px;
	color: #ccc;
	text-transform: lowercase;
	margin-top: -15px;
	}

	/*navigationlinks*/
	.navigation a {
	text-align: center;
	padding: 30px;
	margin-bottom: 15px;
	font-family: arial, sans-serif;
	font-size: 20px;
	}

	.navigation a:link {
	color: #cefa48;
	}

	.navigation a:hover{
	color: #111;
	}

	/*Sidebar*/

	#sidebar h1 {
	padding-left: 0px;
	font-family: "century gothic", arial, georgia, sans-serif;
	font-size: 14px;
	color: #cefa48;
	text-align: left;
	font-weight: lighter;
	}

	#sidebar ul {
	list-style: none;
	margin-left: -20px;
	}

	/*Comments*/

	#commentlist li , .singolocommento li {
	list-style-type: none;
	padding: 0px;
	width: 470px;
	}

	div.bubble {
	width: auto;
	margin-bottom: 24px;
	border: 0px solid #ccc;
	}

	div.bubble cite {
	position: relative;
	margin: 0px;
	padding: 7px 0px 0px 0px;
	top: 6px;
	background: transparent url(tip.gif) no-repeat 20px 0;
	font-style: normal;
	}

	a.author, a.author:active, a.author:visited {
	text-decoration: none;
	font-family: arial, "century gothic", georgia, "times new roman", sans-serif;
	font-size: 17px;
	font-weight: lighter;
	text-transform: uppercase;
	letter-spacing: -1px;
	color: #ec008c;
	}

	/* extras */

	a, a:visited, a:link, a:active { color: #ec008c; text-decoration: none; background-color: inherit;}
	a:hover{ color: #282828; text-decoration: none;}
	b, strong, em, i{ color: #4fd0ad; background-color: inherit;}
	u{ text-decoration: none; color: #d4eb89;border-bottom: 1px solid #d4eb89; background-color: inherit;}

	img {border:0px;}

	.search, #searchsubmit {
	width: 75px;
	}

	input, textarea, select {
	background-color: #282828;
	color: #ccc;
	font-size: 11px;
	font-family: "lucida grande", sans-serif;
	border: 0px;
	}

The final product!

You can download the files used in this tutorial here.

If there’s anything else you want to know please comment, If I’ve missed anything do tell me!