Try Tuts+ Premium, Get Cash Back!
Developing Your First WordPress Theme: Day 3 of 3
basix

Developing Your First WordPress Theme: Day 3 of 3

Tutorial Details
  • Program: HTML/CSS Editor of choice
  • Difficulty: Medium
  • Estimated Completion Time: 3 hours
This entry is part 3 of 3 in the series Developing Your First WordPress Theme

Themes are a huge part of what makes WordPress as popular as it is, and in this three-part series we’ll take you through a step-by-step process that results in a completed, functioning WordPress theme. In part three, we’ll be implementing the comment system, adding sidebar widgets, and wrapping everything up!


Part Three

Welcome to the final part of this three-part series on developing a WordPress theme from scratch. Last time we built the basic structure of a theme, this week we’re going to add the missing pieces and finish off our first theme.


Our Theme So Far

So last time around we converted our standard HTML/CSS design in to a working WordPress theme which could be selected in the dashboard. The theme has a working front page, can show single posts/pages and the navigation. The first thing we’re going to look at is the sidebar and how to incorporate widgets in to it.


Sidebar Widgets

Before we begin, we’ll create a simple text widget in WordPress so we can easily see when the widgets are working. To do that we’ll head to Widgets under the Appearance drop down in the dashboard.

As you can see, WordPress has detected that we don’t have any areas setup in our theme to display any widgets. In order for WordPress to allow the use of widgets, we need to register some areas in our theme where widgets can be displayed – the two most common being the sidebar or the footer.

Of course widgets aren’t restricted to these two locations, they can go anywhere – they can even be broken up. A common practice is to create a location called ‘sidebar top’ and another called ‘sidebar bottom’. Between these two locations, sites can show ads or have anything else custom to their design – of course ads can be widgets too, but some designs have different ways of dealing with things.

In our theme, we’re going to simply have one area – the sidebar. To do this, we need to open up our currently blank functions.php file. Inside this file, paste the following code;

<?php
if ( function_exists('register_sidebar') )
	register_sidebar(array(
	'name' => 'sidebar',
	'before_widget' => '<div class="sidebar-box">',
	'after_widget' => '</div>',
	'before_title' => '<span class="sidebar-title">',
	'after_title' => '</span><div class="dots"></div>',
));
?>

Now if we head back to the dashboard and go to Widgets under Appearance, the page should look a bit more like this (although without the text widget, we’re going to add that now);

WordPress now knows our sidebar exists and we can drag widgets from the Available Widgets panel in to our sidebar. For now, drag across a simple text widget. Set the title to “Our First Widget” and the text to anything you’d like. Make sure you enable the automation of paragraphs.

With this done, we now need to add some code to our theme to let it know where this specific widget location is, so open up sidebar.php. Since sidebar content is now automatically generated, we can replace the code in this file with the following;

		<div id="sidebar">
			<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar("sidebar") ) : ?>
			<?php endif; ?>
		</div><!-- sidebar -->		
		<div class="spacer"></div>
	</div><!-- wrapper -->
	</body>
</html>

With this code in place, when we visit the front page of our theme we should the following (if your paragraphs are not styled, be sure you ticked the automatic paragraphing option under the edit text widget window);

Great, we now have a working widget-ready sidebar! It’s easy to repeat this functionality elsewhere using the same concept; name the widget-ready area, set the styling options in functions.php and paste in the widget displaying code.


Comments

The final river to cross before our theme is completed is comments. Comments can make or break a blog, it’s imperative that comments are implemented in our theme and conform to the standard UI we’re so accustomed to.

Comments work similar to displaying posts and so on – by using a loop. The loop cycles through each comment for a specific page, post (or ID) and allows us to output it however we want. Comments are largely configured from the dashboard, meaning we theme developers have less decisions to make and users have more – a goal that many think we should strive for in theme development.

As a quick recap, last week when we implemented our single post and page files, we added the following line after the content;

<?php comments_template( '', true ); ?>

This function loads the comments file. The first parameter, which we have left blank, is the name of the file. If left blank then the function will default to loading comments.php, which is what we are using. The second parameter specifies whether or not we wish to separate the comments by type, which we do.

There are three things we want to do here;

  • Display a title with the number of comments (if any).
  • Loop through and display all the comments.
  • If allowed, display a form to add a comment.

The Title

So, first of all the title. Much like how we displayed the comment count in index.php, we want to have a dynamic title that changes according to the amount of comments. For no comments we’ll simply display there are no comments (or we could add a ‘Be the first’ message). For 1 comment or more, we’ll display the count (removing the ending ‘s’ if only one comment exists.

<?php if ( have_comments() ) : ?>
<h4><?php printf( _n( 'One Comment', '%1$s Comments', get_comments_number() ),number_format_i18n( get_comments_number() ) );
?></h4>

// Comment loop goes here

<?php else: ?>
<h4>No comments</h4>
<?php endif; ?>

Breaking it down, we’re using the have_comments() function to check there are comments to display. If there are, we’ll display how many using some simple PHP number formatting. If there are not, we’ll simply display a title stating that and we won’t attempt to run the comment loop as we know no comments exist.

If we visit a post with a comment now, it should look like this;

The Comment Loop

Our comment loop looks like this;

<?php foreach ($comments as $comment) { ?>
<div class="comment">
	<a name="comment-<?php comment_ID(); ?>"></a>
	<?php echo get_avatar( $comment->comment_author_email, $size = '40'); ?>
	<div class="comment-right">
		<span class="comment-author"><a href="<?php comment_author_url(); ?>"><?php comment_author(); ?></a></span> <span class="comment-date">on <?php comment_date(); ?></span>
		<p><?php echo $comment->comment_content; ?></p>
	</div>
	<div class="spacer"></div>
</div><!-- comment -->
<?php } ?>

Paste the above code in to the comments.php file, replacing the commented line we left earlier. A large amount of the code is simply design markup. So let’s break it down, here’s what the code looks like without any of the HTML;

<?php foreach ($comments as $comment) { ?>

		<?php comment_ID(); ?>
		<?php echo get_avatar( $comment->comment_author_email, $size = '40'); ?>
		<?php comment_author_url(); ?><?php comment_author(); ?><?php comment_date(); ?>
		<?php echo $comment->comment_content; ?>
		
<?php } ?>

As with most things in WordPress, the simple naming conventions make things quite self explanatory. First of all we’re establishing the comments loop using a simple foreach statement. From there on we use a series of inbuilt methods and functions to display each piece of information.

The comment_ID() function returns the unique identification number for the comment. When we have our HTML in place, we put this ID in to an anchor (#comment-[id]) so that it’s possible to jump and link to specific comments.

Next we use get_avatar(). This is a fairly new function (implemented in WordPress 2.5.0 onwards) that makes use of the extremely popular Gravatar service. The two parameters we need to pass are the email of the user, to determine which gravatar to fetch, and the size. We pass 40, meaning the image returned will be 40px by 40px.

Next up we use two pieces of information about the author, the authors URL (this could be to the authors personal website or to a profile – customizable in the dashboard) and the authors name. These two pieces of information are supplied by comment_author_url() and comment_author(), respectively. Next we use comment_date() which can take a parameter to customize how the date should be displayed, otherwise it uses the default date format set in the dashboard.

Finally, the comment content itself is displayed using $comment->comment_content;.

The Form

Now that we have a title and the comments being displayed, all that is left to do is allow users to add their own comments. This is mostly just styling as so long as we supply the correct information in $_POST format, WordPress will take care of all the validation and so on. The code for our form is as follows;

<?php if ( ! comments_open() ) : ?>
	<h4>Comments are closed.</h4>
<?php else: ?>

<h4>Leave a Comment</h4> 
<a name="comments"></a>
			<form action="<?php bloginfo('url'); ?>/wp-comments-post.php" method="post" id="commentform"> 
				<input type='hidden' name='comment_post_ID' value='<?php echo $post->ID; ?>' id='comment_post_ID' /> 
				<input type="text" value="Name" name="author" onfocus="if(this.value == this.defaultValue) this.value = ''"><label>Name / Alias (required)</label><br /> 
				<input type="text" value="Email" name="email" onfocus="if(this.value == this.defaultValue) this.value = ''"><label>Email Address (required, not shown)</label><br /> 
				<input type="text" value="" name="url"><label>Website (optional)</label><br /> 
				<textarea rows="7" cols="60" name="comment"></textarea><br /> 
				<input type="submit" value="Add Your Comment" /> 
			</form>

<?php endif; ?>

We use a simple if statement to check if this particular page or post has comments allowed, if not then a message stating this is shown, otherwise our form is displayed.

Comments must be submitted to the wp-comments-post.php file using the POST method. The values that must be included in order to make a successful comment are;

  • comment_post_ID – the ID of the post/page
  • author – the name of the author
  • email – the author email
  • comment – the comment content

Of course, url is also accepted, but it is optional. If a user leaves the field blank, then WordPress throws no error. It’s good practice to let the user know that the URL is optional.

The Result

Now if we visit a post with a comment on it (with comments enabled) we will see this;

Great, we now have a working theme with a working comments system! There are many other options to explore with comments, such as adding an edit/delete button for the admin or nested comments. Although beyond the scope of this series, features like these are definitely worth looking in to and greatly increase a themes value.


The WordPress Footer

One final touch to complete our theme needs to be done in sidebar.php as this is where we close our theme. Before the final body tag, we need to add the wp_footer() method like so;

		<div id="sidebar">
			<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar("sidebar") ) : ?>
			<?php endif; ?>
		</div><!-- sidebar -->		
		<div class="spacer"></div>
	</div><!-- wrapper -->
	<?php wp_footer(); ?>
	</body>
</html>

This is a WordPress hook that allows plugins to output anything needed before the theme closes. An example of this is the Google Analytics plugin, which needs to add its javascript at the end of the HTML.


Job Done!

This series has been an introduction to theme development, showing you how a theme fits together and what resources are needed. Hopefully you have found something to take away, even if you have worked on themes before.

Although not difficult, WordPress themes can range from a simple personal layout like we’ve created here, all the way up to complex magazine-style themes with multiple custom plugins and options pages.

Thanks for reading, and any questions/comments or requests for similar tutorials can be left below in the comments!


Other parts in this series:Developing Your First WordPress Theme: Day 2 of 3
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.adrianflorescu.info/ Florescu Adrian

    Thank you for this tutorial series! I never knew how to make widgets work, but thanks to you, now I know how, and in the nice way!

    Thank you!

  • http://www.scriptedpixels.co.uk Kam Banwait

    Awesome 3 part tutorial Dan, really hope to see more like this on this new site.

    Easy to follow with clear images. Will start looking at making this mobile friendly in the next few weeks :)

  • Techeese

    Now that this is complete. I’m going to re-read this and start with the given template then move to other templates i made, thanks.

  • http://www.chipbennett.net/ Chip Bennett

    Is there any particular reason you’re using custom markup for the comment list and comment reply form, rather than using wp_list_comments() and comment_form()? (Note that if you particularly need your custom markup for the comment list, it can be passed via callback to wp_list_comments().)

    Also, I would strongly encourage removing the function_exists() conditional from calls to Widget-related functionality. Those functions have been around in their current form since WordPress 2.8, and it’s probably not a good idea to encourage or facilitate the use of such old versions of WordPress.

    • Brandon Jones

      I thought the same thing when I read the comments section, but I think it’s important to at least know how to do it both ways for the sake of learning the ins and outs… Although, for the record, we’ll be having a series of 3 posts this month that are fully dedicated to comments inside WordPress that will get a lot more advanced. ;) Thanks for the comment Chip!

      • http://www.chipbennett.net/ Chip Bennett

        I would actually say that hard-coding the comment list and (especially!) the comment-reply form is doing it wrong at this point. Plugins depend on a lot of hooks in the markup provided by wp_list_comments() and comment_form(), as well as core WordPress features such as threaded and paginated comments that are otherwise unavailable (or considerably more difficult to implement).

        I’ll look forward to reading the upcoming tutorials! If you need any help with customizing the output of the core functions, I’d be happy to help.

        • Brandon Jones

          Thanks Chip! I’d actually welcome any feedback like this – it’s one of those things that you can do a few different ways, so seeing any insight into innovative or unique ways of handling it is always welcomed!

          • NakkiNyan

            Well I really hope WordPress 3.2 is used next time so we can take advantage of all the new features and make sure we are using the correct markup.

    • http://contempographicdesign.com Chris Robinson

      Also gotta agree with Chip, definitely should be using the correct conventions — hard coding the comment list and comment form is no bueno.

  • http://grafo.graftek.net/ Muhammad Bilal

    Hi
    Its a really great article.
    i have created my own blog with the help of these articles.
    Thanks wp.tutsplus.com.

  • http://www.renderedcanvas.com Leon

    This series of tutorials really answered a lot of questions for me as to how WordPress can be used as a tool of a designer. Thanks for posting this again.

  • Ian

    Great series, very informative. I’m really excited to a wordpress tutsplus site but how come it doesn’t have a spot on the tutsplus homepage?

  • http://www.learneveryday.net arifur rahman

    how can we format multiple level comment format. as in your code only one level comment is formatted.

  • http://www.alohastatemedia.com nate

    So, last time you promised a lot more than just comments. I’m disappointed!

    Quote from day 2

    “Next time we will look at adding a functional sidebar that’s widget ready, dynamic post types, custom fields and wrapping up the final few elements in the theme!”

  • ramon

    Now the next big step wp tuts could is make screencast with tutorials like this and i guarentee that it would be awesome for many people

  • Jack

    Job well done!

    I really liked your clear explanations. Some nice stuff I hadn’t seen in other ‘build a WordPress theme’ tutorials.

    Possibly in the future you could create a tutorial that has a static front page with a side bar that shows post snippets from other pages in the blog.

    Anyways, thanks again.

  • http://ilhamiozen.co.cc CCW

    Thanks. It’s a nice tutorial

  • http://arifriyanto.com/blog Arif Riyanto

    Complete! great tutorial bro

  • Zaw Tun Aung

    As a beginner, I hope to see more similar tutorial like this.
    I really much appreciate about this tutorials.

  • http://unrelatedmedia.ca Neil Davidson

    Yeah, this tutorial series missed a lot of the things it stated it would involve. To fix a couple important parts that the author said would be included here are some alternate tutorials:

    WordPress Options, on Tutts+
    WordPress Options Panel

    Custom Post Types

    If I missed some of the features this 3 part tutorial was supposed to have let me know and I’ll fill in the rest of the blanks.

    • David Appleyard

      Though we might have missed a few things here, I’m sure we’ll be covering them in other tutorials in coming weeks. Don’t worry :-)

  • Joshua Brown

    Unless I missed it, I think you are missing the <?php wp_head(); ?> from the header.php.

    wp_head(); is used by most plugins to insert scripts, stylesheets, meta tags, etc… into the header.
    Without it you will find it very hard to get plugins working.

    Thanks for the tutorial though.
    Looking forward to more.

    -Josh

  • http://laf4free.blogspot.com Melvin

    comment_content();?>

    This is not working….

  • Mark

    This is what I’ve been looking for about a week. Thanks! :D

  • http://zockworkorange.com David

    I was hoping you would include the options page mentioned on the first day in your tuorial. I’ve never done tha so I would love to see a tutorial on that.

    • Blair

      This part of the code is not working for me also. Any help?

      number_format_il8n ( get_comments_number() )

  • Michael

    “This series has been an introduction to theme development ” .. yes, and this was not the approach that I was expecting

    IMHO I would have prefered that you looked at each part of the theme in a detailed tutorial or two ( hierarchy, options, comments, archives, footer, sidebar, widgets, menus, ,custom post types etc) and THEN put it all together in a series about themes. with references to the detail already covered.

    Theme creation is a huge , ambitious topic and it was a suprise to see the series so early in your sites evolution. ..

    my preference : I like smaller chunks covered really well in preference to vast topics covered by only touching the surface …

    • http://www.markupwiki.com Vijay

      but the title clearly shows developing your “FIRST WORDPRESS THEME” and I think for beginners, it is very easy and useful tutorial.

  • http://crazyhunk.com Crazyhunk

    wonderful tutorial, very handy for a guy like me who is starting out in wordpress … :)

    Thank You

  • http://www.customicondesign.com CUSTOM ICON DESIGN

    It’s really great tutorial in the 3 days. it’s really useful for beginner. But not for experience in wp.

  • Rodolphe

    Theme development is a great topic, but as Michael said it’s huge and ambitious. I don’t think you can cover this so quickly. It would be nice to enhance those 3 tutorials with extra ones.

    Anyway, thanks.

  • Varun

    This was a nice tutorial. I want request some further information or guidelines on releasing a wordpress theme for the first time.
    Thanks.

  • http://coderbay.com Coderbay

    Nice Tutorial

  • http://sunplanet.com geoge
  • http://www.ab-c.com.ar Lautaro

    Hi,

    after developing a theme following this steps, when i submit posts, comments or save something in the admin panel i get a blank page.

    Any idea?

    I’m using wordpress 3.2.1

    Thanks!

  • http://inglesnarede.com.br Renato Alves

    I’d love many more tutorials like this. I’m in the process of my first WordPress theme (blog redesign) and would love more information about how to create a wordpress theme from scratch.

    Thanks alot for this series, it helped and will even more in my personal projects. :)

  • http://webmasterinexas.com jerrylee

    Hello, thanks for the tutorial. You obviously put a lot of time and effort into, and it’s great. When I started in 1996, there were no resources like this, so thanks.
    I am having an issue with the widgets/sidebar. It is not showing up. I am not showing any errors, but it’s just not there. I have added several different widgets, but nada.
    I checked out twentyten, and the sidebar code is different, I am wondering if this tut is on an older version of WP? You have

    and twentyten has
    if ( ! dynamic_sidebar( ‘primary-widget-area’ ) ) : ?>
    I realize that things can be done different ways, and this is probably not the problem, and as I don’t see any others mentioning this, it is probably an error on my part. I am doing this locally, so I copied it over to http://webmastersintexas.com/tutorials/wordpress/ in case you have a minute to check my work

    Thanks again! I hope to see more along these lines.

  • Anon

    Great tutorial, thanks!

  • http://www.markupwiki.com Vijay

    Awesome tutorial Dan! very well explained and easy to understand, for designers who are not well versed in PHP, I think this tutorial is best for them to power their design with wordpress…thanks for sharing with us :)

  • http://blog.tsem-webdesign.at tsem

    Really good job – I must admit, that I just read the comment-section. In fact this tutorial was the only, really good explained and un-decorated one. I was searching for a raw, uncomplicated, undformated comment-using tutorial.

    Thx!

  • http://layersfactory.com Dhiera

    Dear,Author…
    If i inserted the Menu, Why it can’t look like Dropdown ?
    On WordPress 3.0 The Menubar can be Drop Down .
    we Just drag the Category on Dashbord section .
    May i know , How to Make WordPress 3.0 Dropdown Menu ?

  • Wilhelm Wanecek

    Hi!
    Great tutorial Dan! I don’t know what I did wrong, but the admin bar kinda messed up. It’s not really a bar either, it looks like it doesn’t have any styles added to it. What did I do wrong?

  • Weerayut Teja

    Thank you for this tutorial, It’s useful article, easy and straight forward.

  • http://8mediaeg.com 8MEDIA

    Quick ,, clean ,, and simple lessons .. thanks for your time :D

  • http://www.santiagoarcucci.com.ar Santiago

    Great tutorial! Very useful.
    Thank you very much Dan!

  • Kevin Mata

    Pffff, the best wordpress-theme-making tutorial EVER. This is the only one I could follow perfectly, my CSS/XHTML theme is now working with wordpress and it wasn’t that hard! Thanks a lot for this.

  • Pingback: Tema wordpress

  • Munirah

    Thank you very much for the very easy to follow tutorial on developing theme. I have been looking to develop a theme from scratch for a very long time but all the tutorials out there were just not it for me, I couldn’t follow them till the end because they were not that clear in details. But I have been able to follow this in every single step with a layout I design myself, and successfully completed it.

    Thanks a lot for sharing…

  • http://www.gavinflood.com Gavin

    Starting an internship in January where they do a lot of WordPress powered sites. Have been trying to find a simple tutorial like this for ages, but this has helped tremendously! Thanks!

  • Vai

    Dan,
    First and foremost thank you for taking time out of your schedule to write a tutorial that is clear and concise.

    To those people who had to complain about this and that missing…. Do you know what it takes to write a tutorial? Do you have the knowledge to write a tutorial like this? If you did, then you wouldn’t be here reading this one… So, just say thanks remember what you were taught, it’s better to have something then naught and go about your business.

  • http://www.loveindigan.com/journal/ Benjamin

    Hello,

    Great tutorial! It was very informative and easy to follow. I’ve just wrapped up my template, although after posting my 2nd blog entry I noticed that my sidebar is stuck to my first post. I’ve gone through my code and I did not notice any unclosed tags. Any help you could provide would be most appreciated. Thank you!

  • http://www.nge-game.com Apri

    That’s really great tutorial to follow, i have already done and this work great !
    Many thaaaaaanks :D

  • http://www.RgreenLawn.com Ryan

    Great tutorial. However, I am a beginner and have lots of questions. One question I have is how to use what we’ve built here and use for more than one application. Specifically, I’m talking about moving elements around. For instance, I would like my footer at the bottom of the page and 100% width just like the header. I am using Expression to do all my CSS modification. I can modify the HTML in there, which updates the stylesheet. However, if I change the layout of the page, I need to somehow correlate that layout change in the php template files, which seems to be my biggest hurdle. My focus right now is the footer. You said the sidebar has to come after the footer in the php template files. But if I move the footer outside of the container, things get pretty screwy. So, all in all, how can I move the footer to the bottom of the page, with 100% width, and not screw up my sidebar? Thanks!

  • Gus

    Great tutorial, thanks!!!

  • http://www.projapotibd.com osman

    nice and grate tutorial .thanks for tutorial

  • Sam

    Hi! Would be great if someone could help!!

    I’m pressing the “leave a comment” button and nothing is happening. I am using hte un-modified source codes too in this tutorial, so I do not know why this is….

    Has anyone else had this problem and is there a fix?
    Great tutorial other than this though!

  • Stew

    Thanks for the series. It helped me in many ways. But I think there is a lack of information on different points for a better understanding of the the syntax.

  • Miro

    I have a problem so if someone can please help me. I understood this tutorial and it is pretty nice, easy and very simple and thank you for that. But I encountered a sidebar problem. I am making a nice theme with a few sidebars and now it happened that my sidebars dont format widgets regulary. I mean when i drag a widget into sidebar it somehow closes inside widgets functions and i only can click on save or delete and ater that it opens again to format it. Sometimes a cant dragout a widget from sidebar and have to wait for a few seconds to do it or it just goes back into sidebar. Is there any kind of solution for this?

  • http://www.simonswiss.com Simon

    Awesome introduction, thanks!

    During the whole tutorial, i was wondering when the navigation bar would finally come up on my site – it did right at the end when i added !

  • andrei

    Hi, really super tut for beginners :)

    I am trying to figure out how to move the sidebar to left instead of right. I looked on wordpress website and others on google but couldnt find anything to help me having the sidebar moved to left side. Please help.

    thanks

  • http://www.accretetechnology.com/ Mohammed Aarif

    Thank you very much sir,
    I have learned many more about theme development in WordPress with help of this 3 days of tutorials
    thanks again sir

  • Sagar

    Thanks! I’ve seen many tutorials but i think this is the only one which calls sidebar after footer. May be the design is demanding that way! And I’ve one small doubt. Why and are starting in header.php? Is that too because the design is like that?

  • Zanc Razvan

    Can you please explain how to create an image slider like this one : http://themeforest.net/item/swagmag-wordpress-magazinereview-theme/full_screen_preview/1576310 that I can control it from the admin panel.

  • Guest

    // Comment loop goes here

    No comments

    where to add this code

    • Dirk Nyhof

      No one knows what you are asking, please specify.

  • Guest

    // Comment loop goes here

    No comments

    where to add title code

  • yasir

    where to add title code

  • Pingback: Xegai.ru » Developing Your First WordPress Theme: Day 3 of 3

  • migaber

    thank you for the rest of this series :)

  • Sam

    Nicely done tutorial. Its very much useful for beginners. everyone dont miss it.

  • http://twitter.com/anirib Irina Borozan

    Great tutorial for beginners! Thanks!

  • http://www.openeshore.com/wordpress-development.htm WordPress Development

    I read all your previous post including this third post of developing first wordpress theme and got complete guidance. Such an amazing articles all were. This post is very helpful for all the people who looking for developing their first wordpress theme.