In this tutorial I’ll show you how a WordPress theme comes together.

I’ll walk you step by step through the html, css and WordPress PHP functions and how they work. I will use the default theme in WordPress to start out, but then will create more complicated themes as the tutorial continues.

Here are some tutorials you may need to understand this tutorial: HTML, CSS, PHP, MySQL, and JavaScript.

All of the code follows the video like always. I mentioned a few links during the video tutorial and they are available here:

If you find this article helpful, please click here [googleplusone] so more people can find this 🙂

Commented WordPress Theme Files from the Video

* @package WordPress

* @subpackage Default_Theme

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “”>

<html xmlns=”” <?php language_attributes(); ?>>

<!– language_attributes() spits out dir=”ltr” lang=”en-US” –>

<!– The profile provides you with a way to define your relationship to any links on your blog –>

<head profile=”″>

<!– bloginfo() displays blog info based off of the parameters you send it name, description, admin_email, url, wpurl, stylesheet_directory, stylesheet_url, template_directory, template_url, atom_url, rss2_url, rss_url, pingback_url, rdf_url, comments_atom_url, rdf_url, charset, html_type, language, text_direction, version –>

<meta http-equiv=”Content-Type” content=”<?php bloginfo(‘html_type’); ?>; charset=<?php bloginfo(‘charset’); ?>” />

<!– wp_title() displays the title of the page. &laquo represents <<, but you can define other seperators. If true you echo the title to screen. If false a php string is returned. right defines where the title shows up in relation to the seperator –>

<title><?php wp_title(‘&laquo;’, true, ‘right’); ?> <?php bloginfo(‘name’); ?></title>

<link rel=”stylesheet” href=”<?php bloginfo(‘stylesheet_url’); ?>” type=”text/css” media=”screen” />

<link rel=”pingback” href=”<?php bloginfo(‘pingback_url’); ?>” />

<style type=”text/css” media=”screen”>

<!– $withcomments is a global variable that defines if comments should be displayed or not –>

<!– is_single() checks if only a single post is being displayed. If so dont display a sidebar. Can also be used to check if post 17 is being displayed is_single(’17’) or if a post with a specific title is being displayed is_single(‘Post Title Here’) –>


// Checks to see whether it needs a sidebar or not

if ( empty($withcomments) && !is_single() ) {

#page { background: url(“<?php bloginfo(‘stylesheet_directory’); ?>/images/kubrickbg-<?php bloginfo(‘text_direction’); ?>.jpg”) repeat-y top; border: none; }

<?php } else { // No sidebar ?>

#page { background: url(“<?php bloginfo(‘stylesheet_directory’); ?>/images/kubrickbgwide.jpg”) repeat-y top; border: none; }

<?php } ?>


<!– is_singular() checks if a single page or post is being displayed. –>

<!– wp_enqueue_script() is used to call built in javascript scripts. This one sets up comment threading on the screen

wp_enqueue_script(‘jquery’) would load the jquery framework (More Can be Found Here

wp_register_script(‘myjscode’, ‘url of script’, ‘array of needed scripts’, ‘version’, ‘if true place in bottom of body’) is used to create a new script –>

<?php if ( is_singular() ) wp_enqueue_script( ‘comment-reply’ ); ?>

<!– wp_head() provides you with a way to run custom functions before the head is closed. These are used by plugins. This is called a WordPress hook that allows you to hook your functions into the WordPress code –>

<?php wp_head(); ?>


<!– body_class() generates a custom class id based off of what page your user is currently on. You could also define a custom class by just providing the class name you created. body_class(‘myClass’) –>

<body <?php body_class(); ?>>

<div id=”page”>

<!– get_option(‘home’) returns the blog url just like bloginfo(‘url’) this is only used when you want to move your WordPress folders outside of the root directory –>

<div id=”header” role=”banner”>

<div id=”headerimg”>

<h1><a href=”<?php echo get_option(‘home’); ?>/”><?php bloginfo(‘name’); ?></a></h1>

<div class=”description”><?php bloginfo(‘description’); ?></div>


* @subpackage Default_Theme

get_header(); ?>

<!– Get header calls for the header.php file to be executed –>

<div id=”content” class=”narrowcolumn” role=”main”>

<!– This is the beginning of what WordPress calls the loop. It loops through every post based off of the values stored in wp_query. wp_query will contain information on how many posts to display and how they qualify for displaying based off of categories, ids, author, page, etc. –>

<!– have_posts() basically asks wp_query if any posts qualify for displaying –>

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

<!– While there are still posts to display the_post() continues to load post data –>

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

<!– post_class() prints to screen any class id specific to this post –>

<!– the_ID() prints out the id that is specific to the post –>

<!– A permalink is the permanent url of your posts. the_permalink() prints that link out to screen –>

<!– The permanent link to part prints out Permanent Link to… followed by the title of the post, which is provided by the_title() –>

<!– the_time() prints out the date and time when the post was created –>

<!– the_author() prints out the authors name –>

<div <?php post_class(); ?> id=”post-<?php the_ID(); ?>”>

<h2><a href=”<?php the_permalink() ?>” rel=”bookmark” title=”<?php printf(__(‘Permanent Link to %s’, ‘kubrick’), the_title_attribute(‘echo=0’)); ?>”><?php the_title(); ?></a></h2>

<small><?php the_time(__(‘F jS, Y’, ‘kubrick’)) ?> <!– by <?php the_author() ?> –></small>

<!– the_content() prints the contents of the post up till the more tag is reached. You can define the text to display for the more tag as they did in the string below –>

<div class=”entry”>

<?php the_content(__(‘Read the rest of this entry &raquo;’, ‘kubrick’)); ?>


<!– the_tags() returns all of the tags associated with the post –>

<!– get_the_category_list() returns all of the categories this post is associated with seperated by the defined seperator –>

<!– If a person who is logged in and has permission to edit the post is on the page edit_post_link() displays a link that allows them to edit the page –>

<!– comments_popup_link() displays a custom message based off of the number of comments. comments_popup_link(‘No Comments’,’1 Comment’, ‘% comments so far’, ‘comment-class’, ‘Comments are turned off’) –>

<p class=”postmetadata”><?php the_tags(__(‘Tags:’, ‘kubrick’) . ‘ ‘, ‘, ‘, ‘<br />’); ?> <?php printf(__(‘Posted in %s’, ‘kubrick’), get_the_category_list(‘, ‘)); ?> | <?php edit_post_link(__(‘Edit’, ‘kubrick’), ”, ‘ | ‘); ?> <?php comments_popup_link(__(‘No Comments &#187;’, ‘kubrick’), __(‘1 Comment &#187;’, ‘kubrick’), __(‘% Comments &#187;’, ‘kubrick’), ”, __(‘Comments Closed’, ‘kubrick’) ); ?></p>


<!– endwhile ends the looping through the posts. Everything that follows this will show up at the bottom of the page –>

<?php endwhile; ?>

<!– next_posts_link() prints out a link to any additonal posts that couldn’t fit on the current page. You can also define what message should print and what symbol should be shown &laquo equals << –>

<!– previous_posts_link() works in the opposite way of next_posts_link() –>

<div class=”navigation”>

<div class=”alignleft”><?php next_posts_link(__(‘&laquo; Older Entries’, ‘kubrick’)) ?></div>

<div class=”alignright”><?php previous_posts_link(__(‘Newer Entries &raquo;’, ‘kubrick’)) ?></div>


<?php else : ?>

<!– _e() prints out the error message you provide if no posts were found –>

<h2 class=”center”><?php _e(‘Not Found’, ‘kubrick’); ?></h2>

<p class=”center”><?php _e(‘Sorry, but you are looking for something that isn&#8217;t here.’, ‘kubrick’); ?></p>

<!– get_search_form() displays WordPress’s custom search form –>

<?php get_search_form(); ?>

<?php endif; ?>


<?php get_sidebar(); ?>

<?php get_footer(); ?>

* @subpackage Default_Theme

<div id=”sidebar” role=”complementary”>


<?php /* Widgetized sidebar, if you have the plugin installed. */

if ( !function_exists(‘dynamic_sidebar’) || !dynamic_sidebar() ) : ?>


<?php get_search_form(); ?>


<!– Author information is disabled per default. Uncomment and fill in your details if you want to use it.

<li><h2><?php _e(‘Author’, ‘kubrick’); ?></h2>

<p>A little something about you, the author. Nothing lengthy, just an overview.</p>


<!– is_404() checks if a 404 error is being displayed

is_category() checks if a category archive page is displayed

Everything else should make sense –>

<?php if ( is_404() || is_category() || is_day() || is_month() ||

is_year() || is_search() || is_paged() ) {

?> <li>

<?php /* If this is a 404 page */ if (is_404()) { ?>

<?php /* If this is a category archive */ } elseif (is_category()) { ?>

<!– single_cat_title() returns the title for the category if marked true. The first string if defined will print before the category name –>

<p><?php printf(__(‘You are currently browsing the archives for the %s category.’, ‘kubrick’), single_cat_title(”, false)); ?></p>

<?php /* If this is a daily archive */ } elseif (is_day()) { ?>

<p><?php printf(__(‘You are currently browsing the <a href=”%1$s/”>%2$s</a> blog archives for the day %3$s.’, ‘kubrick’), get_bloginfo(‘url’), get_bloginfo(‘name’), get_the_time(__(‘l, F jS, Y’, ‘kubrick’))); ?></p>

<?php /* If this is a monthly archive */ } elseif (is_month()) { ?>

<p><?php printf(__(‘You are currently browsing the <a href=”%1$s/”>%2$s</a> blog archives for %3$s.’, ‘kubrick’), get_bloginfo(‘url’), get_bloginfo(‘name’), get_the_time(__(‘F, Y’, ‘kubrick’))); ?></p>

<?php /* If this is a yearly archive */ } elseif (is_year()) { ?>

<p><?php printf(__(‘You are currently browsing the <a href=”%1$s/”>%2$s</a> blog archives for the year %3$s.’, ‘kubrick’), get_bloginfo(‘url’), get_bloginfo(‘name’), get_the_time(‘Y’)); ?></p>

<!– wp_specialchars() converts special characters into their html entities. You are supposed to use esc_html() instead for future themes. –>

<!– get_search_query() returns the string typed in the search box –>

<?php /* If this is a search result */ } elseif (is_search()) { ?>

<p><?php printf(__(‘You have searched the <a href=”%1$s/”>%2$s</a> blog archives for <strong>&#8216;%3$s&#8217;</strong>. If you are unable to find anything in these search results, you can try one of these links.’, ‘kubrick’), get_bloginfo(‘url’), get_bloginfo(‘name’), wp_specialchars(get_search_query(), true)); ?></p>

<?php /* If this set is paginated */ } elseif (isset($_GET[‘paged’]) && !empty($_GET[‘paged’])) { ?>

<p><?php printf(__(‘You are currently browsing the <a href=”%1$s/”>%2$s</a> blog archives.’, ‘kubrick’), get_bloginfo(‘url’), get_bloginfo(‘name’)); ?></p>

<?php } ?>

<?php }?>

<!– wp_list_pages() returns a list of all pages as a list of links. You can define numerous options in this function which can all be found here –>


<ul role=”navigation”>

<?php wp_list_pages(‘title_li=<h2>Pages</h2>’ ); ?>

<!– _e() prints the string you provide if an error occurs –>

<li><h2><?php _e(‘Archives’, ‘kubrick’); ?></h2>


<!– wp_get_archives() returns a list to all of the archived pages. Multiple options can be found on this page –>

<?php wp_get_archives(‘type=monthly’); ?>



<!– wp_list_categories() retrieves a list of categories as links to them. Options for this function can be found here –>

<?php wp_list_categories(‘show_count=1&title_li=<h2>’ . __(‘Categories’, ‘kubrick’) . ‘</h2>’); ?>


<!– is_home() returns true if your on the main home page. –>

<!– is_page() returns true if your own a regular page. –>

<?php /* If this is the frontpage */ if ( is_home() || is_page() ) { ?>

<!– wp_list_bookmarks() displays all of the links that our defined in the Administration -> Links panel. Options can be found here –>

<?php wp_list_bookmarks(); ?>

<li><h2><?php _e(‘Meta’, ‘kubrick’); ?></h2>


<!– wp_register() displays a link if an administrator is logged in or Register if they aren’t logged in.

wp_register( ‘String to Display Before the Link’, ‘String to Display After the Link’, ‘True Echos a Link / False Returns a String’)–>

<!– wp_loginout() displays a login link or a log out link if the person is logged in. You can redirect the user to a login page automatically if they aren’t already logged in like this wp_loginout(‘loginURL’) –>

<!– wp_meta() provides you with a way to run custom functions before the sidebar is closed. These are used by plugins. This is called a WordPress hook that allows you to hook your functions into the WordPress code –>

<?php wp_register(); ?>

<li><?php wp_loginout(); ?></li>

<li><a href=”” title=”<?php _e(‘This page validates as XHTML 1.0 Transitional’, ‘kubrick’); ?>”><?php _e(‘Valid <abbr title=”eXtensible HyperText Markup Language”>XHTML</abbr>’, ‘kubrick’); ?></a></li>

<li><a href=””><abbr title=”<?php _e(‘XHTML Friends Network’, ‘kubrick’); ?>”><?php _e(‘XFN’, ‘kubrick’); ?></abbr></a></li>

<li><a href=”” title=”<?php _e(‘Powered by WordPress, state-of-the-art semantic personal publishing platform.’, ‘kubrick’); ?>”>WordPress</a></li>

<?php wp_meta(); ?>


* @subpackage Default_Theme

<hr />

<div id=”footer” role=”contentinfo”>

<!– If you’d like to support WordPress, having the “powered by” link somewhere on your blog is the best way; it’s our only promotion or advertising. –>


<!– get_bloginfo(‘comments_rss2_url’) Displays a link to the RSS feed for the site –>

<!– get_num_queries() retrieves the number of database queries issued during the WordPress execution –>

<?php printf(__(‘%1$s is proudly powered by %2$s’, ‘kubrick’), get_bloginfo(‘name’),

‘<a href=””>WordPress</a>’); ?>

<br /><?php printf(__(‘%1$s and %2$s.’, ‘kubrick’), ‘<a href=”‘ . get_bloginfo(‘rss2_url’) . ‘”>’ . __(‘Entries (RSS)’, ‘kubrick’) . ‘</a>’, ‘<a href=”‘ . get_bloginfo(‘comments_rss2_url’) . ‘”>’ . __(‘Comments (RSS)’, ‘kubrick’) . ‘</a>’); ?>

<!– <?php printf(__(‘%d queries. %s seconds.’, ‘kubrick’), get_num_queries(), timer_stop(0, 3)); ?> –>


<!– Gorgeous design by Michael Heilemann – –>

<?php /* “Just what do you think you’re doing Dave?” */ ?>

<!– wp_footer() provides you with a way to run custom functions before the footer is closed. These are used by plugins. This is called a WordPress hook that allows you to hook your functions into the WordPress code –>

<?php wp_footer(); ?>


27 Responses to “WordPress Theme Tutorial”

Greg says:

This is a nice tutorial and I am just cramming all the information I can. I don’t have any knowledge of coding in any language, so it isn’t easy. My biggest issue is finding where to put the images such as the background, sidebar graphics, footer graphics, etc… Any help would be GREATLY appreciated!

Thanks and nice TUT,

I made a tutorial that shows you how to do exactly what you’re trying to do Create Website Layouts.

Here is another one that shows you how to create menus

I will also be creating many custom wordpress themes in my newest tutorial. I hope that helps?

Hi Derek-I am messing around with a blog site I just started and am having some browser issues. Could you explain and/or demo how this little ditty : works?

In addition to having the eyes floating to different positions in various versions of the dreaded MIE, as well as, Opera, I would like to bring in other scripts as well, especially some jquery plugins. The problem I have is where to put them and how to get them to work properly.

As always, thank you for all your help and consideration.

wp_enqueue_script( ‘comment-reply’ );

I tried plunking my script and the http://pointing to it in wp-content but to no avail. Would really like to get this to work. Lots of ideas I’d like to apply.


Thanks for nice tutorial. I am new to wordpress and eager to learn it.
I went through whole tutorial but i couldn’t understand , how to execute index.php on localhost based on the tutorial. Could you please explain this?


If you are using a pc the easiest thing you can do is install apache. Then install the wordpress folder in the htdocs folder.

Otherwise check out my Install WordPress Localhost tutorial if you’re on a Mac or Linux system

Thank you for these excellent tutorials. I have watched all your WP theme, Featured Content and Plug in tutorials. I was hoping you could remind me which tutorial points out how to create the loop to connect your posts to your category. I hope I’m not being too presumptuous by asking. I plan on re-modeling my news site once I’m done through watching your News theme tutorials, but right now just want to make sure I’m creating the loop correctly before moving on to the more complicated stuff. Thank you.

In part 2 of this series I go over how to use the loop, but then cover that topic numerous times throughout my WordPress Theme Tutorial and News Theme Tutorial

I hope that helps?

Hi sir,
Please add me in facebook, if you have any a/c with facebook so I can interact with you. I am opening a web designing business all alone. But I am little bit confused with which domain and web hosting will be good for me. I do see that you suggested, but I m little confused with how can I pay in dollars if I have indian debit or credit card.
I am also getting clients.. but the problem is :
My clients are looking for flash images in wordpress that I am unable to provide.
Please suggest what needs to be done

thank you

I use Go Daddy only because they have never forced me into a dedicated server. It is probably in your best interest to use an Indian hosting company, but maybe not? Feel free to perform a friend request on my facebook page. I’ll add you, but I don’t check it every day. You can always reach me here, or on my YouTube channel. I check those constantly.

I’m not sure what you mean by Flash images. Animations, interfaces, etc.? I have some flash tutorials, but I stopped doing them because Flash is falling out of favor because it doesn’t work on mobile devices. I’ll gladly provide any help I can

Thank you

I’m enjoying your tutorials.

One request: in this tutorial you don’t always highlight the part of the code you’re talking about, and it’s not always easy to see which lines you’re talking about.

Question: The code you’re using has variables such as these:

‘Permanent Link to %s’ ‘%1$s’

Where do they get defined? How does one use them in building a theme?


hi derek,
firstly i wd like to thank you. you are the wordpress guru. you are just unbelievable & outstanding.

Your wordpress tutorials are great.
i want to that i’ve finished all of your wordpress tutorial.

now i want to start making wordpress site. but now i need a suggestion.

as the first time which sort of site i’sd choose to build. very easy or avg?that means i sd start from a easy site or not?

& also i dont know how to upload the site from localhost to ftp. wd you help me, sir?

actually after finishing your wordpress tutorials, i decide to start with wordpress.

so,actualy i want to make wordpress site from scratch and i wd like to you to give me a strategic way or any suggestion for me.

as a beginner any kind of suggestioon for me? i want to be very good in wordpress. and definitely you are my teacher, so any strategic way of starting with wordpress or any suggestion…

i’ll wait for your reply , sir.

Thank you very much 🙂 I greatly appreciate your nice comment.

To make WP themes you have to very extremely good with HTML and CSS. Make sure you understand everything I cover here: HTML Video Tutorial & CSS Video Tutorial.

If you understand that then you just need to understand how WP themes differ from regular web designs. That is covered here WordPress How To. Just follow those tutorials in order. I set everything up in the order in which I thought it should be learned.

I also have every WP tutorial I’ve made here in this list. I hope that helps

I would like to see tutorial on word-press 3.9.1


I watched your first tutorial Vid.
i got the codes but ,, also got an erro

“Parse error: syntax error, unexpected ‘Link’ (T_STRING) in C:\xampp\htdocs\wordpressthree\wp-content\themes\BLANK-Theme\index.php on line 71”

can you help me about this .. i C&P your code..

Leave a Reply Cancel reply

Your email address will not be published.

This content was originally published here.

Leave a Reply

Your email address will not be published. Required fields are marked *