How To Build A WordPress CMS Theme – Part 3: Built In Functions
In Part 1: Theme Basics, we learned what composed a theme and how to get it working inside of WordPress. In Part 2: Let’s Get Started, we looked at using starter themes and the basic header and footer files.
Now it’s time to get a bit more technical. In today’s post, we’re going to learn about some of the most important built-in WordPress functions that turns your code into the perfect CMS.
Just remember this, coding a WordPress site is pretty much EXACTLY like coding a regular website. You’ve got your header and footer includes and your content in the middle. The only difference, is that you replace the content with functions that allow you to use the CMS and store the content inside of a database. This makes it easy for you to update, as well as to change themes in the future.
Let’s get started!
Chapter 8: Introduction to the Loop
The loop is THE number 1, most important function inside of WordPress. Without the loop, you have nothing: no content, no custom fields, no titles, no dates, no blog and no website.
So what is this mysterious loop? Here it is in it’s simplest form:
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> //stuff here <?php endwhile; else: ?>
Doesn’t look like much does it? But from here, we can control what posts, pages and info shows up, as well in what order and any number of options.
In order for the loop to actually show something, we need to tell it what we want. Let’s say this is our blog archives page, and we want to show the title, the date and an excerpt of the post. Here’s what our loop would look like:
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <?php the_title();?> <?php the time('d/m/y');?> <?php the excerpt();?> <?php endwhile; else: ?>
Of course, without any HTML tags, your content will look jumbled, so you may want to put h2 tags around the title.
Now, let’s say you have 5 posts, if this loop is placed within the archives.php or index.php, it will show all 5 posts in order from newest to oldest. Such a powerful function for such small code!
Here are some more useful functions you can use inside the loop to display content.
Display the URL of the post:
<?php the_permalink(); ?>
Display the content of the post:
<?php the_content(); ?>
Display the category of the post:
<?php the_category(); ?>
Display the tags used in the post:
<?php the_tags(); ?>
If you’d like to find out all of the parameters you can use in the loop, check out the WordPress Codex.
Chapter 9: Introduction to the Query
Now that we have our basic loops down, what if we want more control on what shows up in our loop, as well as how it shows up?
Thankfully, the WordPress gods have thought about this already, and have provided us with another great built-in function: the query. Let’s start with the loop we had from above, that shows the title, date and excerpt of a post.
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <?php the_title();?> <?php the time('d/m/y');?> <?php the excerpt();?> <?php endwhile; ?>
Query posts fundamentally changes the way the loop works, and must come before the if statement:
<?php query_posts(); if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <?php the_title();?> <?php the time('d/m/y');?> <?php the excerpt();?> <?php endwhile; ?>
What can query posts do? Let’s say we want to limit the number of posts it shows to 2 and show the oldest first, instead of the newest:
<?php query_posts('posts_per_page=2&order=ASC'); if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <?php the_title();?> <?php the time('d/m/y');?> <?php the excerpt();?> <?php endwhile; ?>
So simple, eh? What if you want to show content from a page, not a post? Simple again!
<?php query_posts('pagename=Home'); if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <?php the_title();?> <?php the time('d/m/y');?> <?php the excerpt();?> <?php endwhile; ?>
This is actually how I do my homepages in WordPress. I’m not a fan of making separate “template” pages for each layout, so I simply put the code on the index page and use a query to pull the content from a page you’ve created and named “Home”. Quick and easy for both you and the client!
If you’d like to find out all of the parameters you can use for query posts, check out the WordPress Codex.
Multiple Loops
Having multiple loops on one page can be a bit tricky. If you’re not careful you can mess the content displaying inside of the loops up and render your site useless. Fortunately, this is yet another issue the spiffy guys at WordPress anticipated.
You can avoid messing up your loops by adding a simply wp_reset_query() function to the end of your loop.
<?php query_posts('pagename=Home'); if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <?php the_title();?> <?php the time('d/m/y');?> <?php the excerpt();?> <?php endwhile; wp_reset_query(); ?>
Unfortunately, you still can’t use a loop inside of a loop (which would’ve come in handy for me more than once) but this still gives you a pretty good workaround for chopping up and piecing content together.
Chapter 10: wp_list_pages Functions
The most popular sets of functions in WordPress are navigation-related functions. For navigation menus, a popular function for dynamically generating them is to use the wp_list_pages WordPress function. Another method for dealing with site navigation was recently introduced in WordPress 3.0: the wp_nav_menu function.
We’ll talk about these two functions, starting with wp_list_pages.
Listing All Pages
If you want to list all of the pages you’ve got (note that pages and posts have different meanings in WordPress vernacular), there’s a simple function for that called wp_list_pages. When used without any parameters, it will list all of your pages in alphabetical order.
<?php wp_list_pages(); ?>
Listing Specific Pages
As with many WordPress functions, the wp_list_pages function takes several parameters. For example, the include parameter allows you to list specific pages by referencing their page IDs, separated by commas (,). The following example will only list two pages (the pages have IDs of 4 and 5).
<?php wp_list_pages('include=4,5'); ?>
Excluding Specific Pages from a List
You can also exclude specific pages using the exclude parameter:
<?php wp_list_pages('exclude=4,5'); ?>
Sorting Pages
As discussed earlier, the default sorting order of wp_list_pages is alphabetical. You can, however, change the order of the listing using the sort_column parameter. The sort_column parameter can have 1 of 7 values:
- post_title – Sort alphabetically (default value)
- menu_order – Sort by page order
- post_date – Sort by date of creation
- post_modified – Sort by time last modified
- ID – Sort by page ID
- post_author – Sort by the page author ID
- post_name – Sort alphabetically by post slug
Here is the code for sorting by creation date instead of the default alphabetical order:
<?php wp_list_pages('sort_column=post_date'); ?>
Specifying the Depth
Pages can have subpages, and subpages can have subpages. What if you only wanted to list top-level pages but exclude their subpages? Controlling the depth works great when using it to generate dropdown menus with submenus.
You can use the depth parameter like so:
<?php wp_list_pages('depth=1'); ?>
Chapter 11: Enabling WordPress 3.0′s Navigation Menu Feature
If you’re wanting absolute control over your navigation, using WordPress 3.0′s new menu function, wp_nav_menu, is the way to go. With this function, you can add categories in menus, submenus and even insert external links into navigation menus.
To take advantage of the built-in navigation menu functionality, first you need to enable it in your theme. In your functions.php file located in the theme directory, you’ll need to add the following:
<?php add_theme_support( 'menus' ); ?>
Next, place the following code in the location where you want the menu to show on your site (this could be in your standard theme template files such as header.php or single.php):
<?php wp_nav_menu( array('menu' => '[Menu Name]' )); ?>
Replace [Menu Name] with what you want your menu to be named.
You’ll then need to navigate to Appearance > Menus and create your menu with the same exact name. Everything from there is simply drag and drop!
Chapter 12: Displaying Blog Information
We’re moving on to getting and working with information about the blog. WordPress has a function for getting and printing your WordPress blog information called bloginfo. This is a good function to use for themes that will be used in multiple domains. There are many parameters you can use for bloginfo; to find all of them, read the bloginfo WordPress Codex documentation.
Getting the Site’s URL
Let’s say your site’s URL is http://example.com. If you want to print this out in the source, you can use the url parameter.
<?php bloginfo('url'); ?>
This works great for absolute link references. For example, if you wanted to reference your logo (let’s say the file name is logo.png) that is in a directory called images, you would do the following:
<img src="<?php bloginfo('url'); ?>/images/logo.png" />
The above outputs:
<img src=" http://example.com/images/logo.png" />
Getting the URL to the Current Theme
To grab the current theme directory’s URL, you can use the template_url parameter. This makes your WordPress themes more flexible so that when you change the domain name or use it in multiple domain names you don’t have to worry about changing anything that references the theme’s location. You can use this parameter a number of ways, such as for referencing custom external stylesheets, images, and JavaScript libraries that are inside the theme directory.
<?php bloginfo('template_url'); ?>
Getting the URL of Your RSS Feed
The bloginfo function can also be used for getting other URLs. For example, if you want to grab the RSS feed URL for your site, you can use the ‘rss2_url’ parameter:
<?php bloginfo('rss2_url'); ?>
If you wanted to create a link to your RSS feed, you could use the following:
<a href="<?php bloginfo('rss2_url'); ?>">Link to RSS feed</a>
Chapter 13: Working with Custom Fields
One of the most powerful functions that WordPress has that seems to take developers a long time to learn is the use of custom fields. Custom fields allow users to add custom name/value pairs typically used for post metadata. For example, users can add a post_thumbnail_url key that has a URL value pointing to the thumbnail image.
Users can add custom fields while they are creating posts and pages in Posts > Add new or Pages > Add new.
I’ve used custom fields for everything — from post thumbnails and changing the background of the individual post to adding custom link and layout areas. It becomes very powerful once you’ve learned it properly.
Getting custom fields can be done from inside or outside of the loop. If you use it outside the loop, you have to reference the ID of the post or page you want the custom field name/value pair from.
Using Custom Fields to Display Image Thumbnails
Let’s say you want to display an image thumbnail in a post.
First, you must create a new post (Posts > Add new). Under the Custom Fields fieldset, type Thumbnail into the Name field and a URI for the Value field. Then publish the post.
Wherever in the loop you want the URI to be displayed, simply use the echo statement to output the result of get_post_meta (which is a function for getting custom fields).
<?php echo get_post_meta($post->ID, 'Thumbnail', true); ?>
To use get_post_meta outside the loop, change $post->ID to the ID of the post. For example, here’s how to print the URL of the thumbnail image for the post with ID of 6.
<?php echo get_post_meta(6, 'Thumbnail', true); ?>
Since we want to display an image, what we actually need to do is use the echo statement inside the src attribute of an img element:
<img src="<?php echo get_post_meta(6, 'Thumbnail', true); ?>" />
The code from above should output the following:
<img src="/images/thumbnail.jpg" />
Part of my functions descriptions were taken from an old post of mine in 2010 at Six Revisions
Upcoming
Next time, we’ll take a look at implementing a regular site into WordPress! If anyone wants to donate a design and HTML/CSS files, leave a link to a preview of the site in the comments area and I’ll pick one!

I’ve design for a hosting company web site (an old and cancelled project) but it’s not sliced, just psd file..
I can send it to you if you want..
Can you just post a link on here from me to check out the design? I’m looking for something that already has CSS/HTML (since I don’t need to explain that to the readers) but I’ll check it out nevertheless
sure it’s link: http://tuncay.demirtepe.com/saveDom.jpg
Oh man I like that design
I like it too, another freelancer from Poland made this for me, but I never find enough time to start it
Hi Amber,
I’m currently working on this site and would love to see how you would turn it into a WordPress theme. Here is the link http://ottawacakecompany.com
Hi George!
Thanks for sending the link, is the client ok with having it on a tutorial? If so, I’ll keep your site in mind for next week, depending on other submissions and will let you know if I choose it. Should I choose it, and actually make it through this whole series and get it turned into a theme (this is tough work!), you’re of course welcome to keep the WP files and use it to be a hero and give your client a free upgrade
Hi Amber,
The client is ok with it.
If it gets picked I have the HTML and PSD files.
P.S. Congrats on your wedding again.
I had just moved my HTML files into that /temp_site_files subfolder when i made my site WP driven the other day with someone else’s theme, but i’d much prefer my actual design to be WP powered… as a visual designer its beyond my ability and budget at the moment. If this sounds good, I can put my HTMLs back and it might not interfere with the live WP version… cool?
Just add a link here if you don’t mind so I can check it out
http://www.robthedesigner.com
I seem to be having a problem with this reply form, so my apologies if a bunch come through when I cannot see any. My site is at http://www.RobTheDesigner.com
Awesome. Moved my HTML files back. They’re gross… as a visual designer I rely on an old version of Dreamweaver that doesnt work with Snow Leopard anymore, and I don’t want to offer web design any longer. Too techy for me.
What’s the address?
You can click on my name up there, but it’s http://www.RobTheDesigner.com.
I would love to see one of our recently revamped sites put into WordPress. You can find it at http://www.architecturalsurfaces.net/index.html
Also, thanks for this great series!
Thanks, I’ll add it to the list of potentials!
Another great post Amber. I have been enjoying reading this tutorial through. It’s been a great help in starting to understand WordPress more.
I’ll submit either of these sites for your consideration.
http://kingsfirewoodandtreeservice.com/
http://www.zellerllc.com/
(The first link is a small site but you can take any creative freedoms that you wish with it also.)
Thanks, I’ll take them into consideration!
I am loving these tutorial posts… massively helpful
I would love to have my site converted to WordPress. It is something I have been thinking about getting done for a little while now so it would be great if it is suitable for what you are after for your next tut.
url: http://www.chrismyersdesigns.com.au
Cheers heaps
I love your website, Chris! I’m not sure if it would be the best to do the tutorial on, since it’s only one page, I won’t be able to show off menus or widgets or anything..i’ll think on it though
Bummer, if it helps at all, the reason I was thinking about converting it to WordPress is to add a blog.
I know it doesn’t add much to the number of pages but cheers for keeping my site in mind.
BTW: congrats on your recent wedding day.
I love you amber, I’m taking on two projects right now and afterwards I’ll be doing my first wp theme! Timing just could not have been any better, lol.
So understanding wordpress is mainly understanding its specific PHP functions? I’m excited, this will be a big help to me.
My projects aren’t finished and are a bit complex, so I’ll refrain from adding any links. Keep up the great work.
Yup, pretty much! and thanks
It’s interesting to see how others set up their WordPress installs, because it can be done many different ways but always generally follow the same guidelines.
I understand for the basics of the tutorial you used custom fields in a simple convenient way, but in a working environment, have you ever used the Advanced Custom Fields plugin or written your own custom fields? ACF has a nice selection of snap-on fields that make it simpler to add more specialized key/value pairs like images, drop-down boxes, toggles, etc.
Great work on the tutorials, your style of writing is relaxed and void of distraction. Easy to digest! When i come across an article on Freelance Folder that i am really enjoying i find myself saying “I bet Amber wrote this” and scrolling to the bottom to see that i was right!
Thanks Ash ^_^
I was wondering if you prefer putting the images for a site in the wordpress theme folders or up on the site itself?
I can see where both come in to play. If you design one theme = one site then putting it in the them makes all the sense. However if you making a theme that should work for any site, requiring /images/logo.png sounds like a better plan.
Just wondering your thoughts.
Hi Mark,
If it’s an image pertaining to the actual theme (backgrounds, buttons, etc), I place it in the theme folder. If it’s a image pertaining to the content, I upload via the media uploader. I’ve never done a theme for multiple users, so I’m not sure how I would do that
Amber, i don’t understand why i should use the custom field for inserting thumbnails. WordPress has allready a buid-in function called featured. I Am an WordPress beginner so i hope you can explain this to me. Thx again for this.great tutorials.
I use custom fields for inserting thumbnails a lot when dealing with multiple thumbnails and sliders