WordPress Development for Beginners: Building Themes

If you’re interested in WordPress development you’ve no doubt tried to customize your own themes, whether that involved simply configuring options in the Customizer or creating a child theme for more complex customizations.

According to the WordPress Codex: “A WordPress theme is a collection of files that work together to produce a graphical interface with an underlying unifying design for a weblog.” Simply put, themes provide a way to “skin” your site, allowing you to modify the way your content is displayed.

This is the third post in our five-part series for beginners, teaching you the fundamental concepts of WordPress development so you can take the leap from tinkerer to developer. By the end of the series, you will be able to create your own rudimentary themes and plugins, and flesh them out with your own features.

In this tutorial, we’ll jump right into theme development. We’ll start with the basic files that make up a theme and progress to working with templates, template tags, and loops, allowing you to display your posts on single, archive and other pages. By the end of this article, you’ll be able to put together your very own theme.

Note: For this series, it’s important that you already have a thorough understanding of HTML and CSS as both of these languages are essential building blocks when working with WordPress.

Let’s get started.

Getting Started

By now, you should already have a localhost environment set up on your machine in which to work and run WordPress. If not, check our part two of this series and scroll down to the bottom to find out more.

If you’re ready to move on, the first thing you’ll need to know is where WordPress stores themes. Themes are usually found in the wp-content/themes directory of your install. If you navigate to that folder in your localhost environment, you should already have a few themes in there, the default WordPress themes. It is possible to change the location of your themes with commands in the wp-config.php file, but this rarely done.

Let’s create a new theme. To do this, there a few fairly easy things you need to do:

Create a new folder in your install’s “themes” directory and name it something unique, like my-awesome-theme.

In this new folder, create two files: style.css and index.php

Open the stylesheet and paste in the following code:

These details will automatically populate the theme details section in the Appearance > Themes screen in the backend of WordPress. The theme name is the only line you must include in the comments, but it’s a good idea fill everything out. Note that the text domain must match the name of the folder (in this case, my-awesome-theme) exactly. This is used for translations, which we won’t get into in this tutorial, but it’s best practice to follow convention.

If you visit the Appearance > Themes section you should now be able to see your theme in the list and even activate it. The theme doesn’t have any code yet so you’ll just see a white screen on the front-end – but we’ll change that very soon!

Our new empty theme
Our new empty theme

How Templates Work

WordPress themes work using template files. It’s actually an ingenious method as it drastically decreases the number of files required for a website to run when compared with regular old HTML. If you have a HTML site, you would need a file for each article you publish. Each file would contain the header of the site, the sidebar, and the footer – and this information would be the same for each file. The only thing that would be different from file-to-file is the content of the article itself.

Since PHP is processed on the server we can even better as far as saving file space goes. Instead of having all of these separate files, we can use just one file, detect the page we’re on and ask PHP to replace placeholders with the actual title of the post and the actual content.

Here’s some pseudo-code to show how this works:

Notice that you don’t see anything hard-coded in the article area. Instead of seeing an actual title, there is a function – the_title() – which is responsible for outputting the title. These functions detect which post is currently requested (based on the URL) and look up the
appropriate information needed in the database.

Thus, we’ve created a file for each and every article on our site, all with one file. Many systems, WordPress included, take this a step even further and separate the header and footer out as well. In fact, a file that governs a single post looks more like this:

Since our website will also have single pages, archive pages, and 404 pages, among others, we might want to reuse the header and footer there as well. Reusable code is what makes server-side coding so helpful and efficient.

How Themes Work

We’ll be using a bunch of template files in our theme to create our website. What we need to know is what files we need to create for what page. This is governed by the WordPress template hierarchy. Let’s take a look at the types of pages we’ll need to think about:

  • Archive pages (category archives, date archives, tag archives, author archives, etc.)
  • Single pages (single posts, single pages, single custom post types)
  • Front page and index page
  • Error page
  • Search results page

It is called a “hierarchy” because WordPress looks for a bunch of different files when determining which specific one to show.

Let’s look at an example.

Say we’re looking at an author archive page, like my posts on the WPMU DEV blog. WordPress first checks if there is a file named author-danielpataki.php in the theme’s folder. If there is, that file is used. Otherwise, it moves on to a file which contains my author ID. I have no idea what my author ID is, but let’s assume it’s 882, in which case the file used would be author-882.php. If that file doesn’t exist it uses author.php, followed by archive.php and finally – if all else fails – it uses index.php, which is a required file so it will exist.

Note that WordPress begins with more specific files and moves toward generalized files. This is useful because, just like we did in the previous section, you can create one file to handle all authors – author.php. However, you may want to make one specific author’s profile different, in which case you could use author-danielpataki.php to make that happen.

Let’s Build a Theme!

When building new themes, I like to start by building a frame in which to work. This usually means creating the header and footer sections first.

Instead of pouring through endless paragraphs of knowledge, I always think it’s best to jump right in and start making something right away because practice makes perfect.

You should already have a theme in place and activated with an empty index.php file and a stylesheet, so let’s build on that.

Building a Frame

I usually create a screenshot first that can be displayed for my theme in the Appearance > Themes screen in the backend of WordPress. This is not important for the build phase of a theme at all, but it immediately gives me something nice to work with and serves as inspiration for my theme. If you have a design of your upcoming theme, use that, or you can use a nice image from an image repository like Unsplash.

While we’re on the subject of images, if you’re creating a theme for the WordPress Theme Directory, you must use CC0 images. This is the “do what you want” copyright license and is rarer than you’d think. All images on Unsplash are amazingly beautiful and CC0, which makes the site a fantastic resource.

Once you’ve found an image you like, cut it down to 880px wide and 660px high, name it screenshot.png and place it in your “theme” folder. If you need a quick fix, I’ve created the image below for you to use as an example. You can download the image here.

A preview of our theme screenshot
A preview of our theme screenshot

In case you’re wondering, the color overlay is based on Pantone’s 2016 color of the year (which is actually two colors this year) – I quite like them! The background image is by Tim Swaan from Unsplash.

The next step is creating the HTML frame of our theme. This includes code that is loaded on all pages, like the HTML head element, doctype, and others.

Let’s start by creating a header.php file. Within that file, we’ll paste the beginning of our HTML code, like so:

We’ll cap it off by creating the footer.php file, which will contain the closing tags for our open elements:

I should point out two important functions in there: wp_head() and wp_footer(). We’ll discuss these functions in next week’s tutorial in this series about widgets and menus when we explore hooks, but for now, you should remember that whenever you make a theme you must put wp_header() right before the closing tag of the head element and wp_footer() right before the closing body tag. These act as markers that help WordPress and plugins inject functionality into your theme.

Now, let’s turn our attention to index.php. If you visit your website at this stage you’ll just get an empty screen. This is because the index file is is empty and the header and footer files are not being used at all.

Let’s change that. Add the following to the index file:

If you load your page now you will see the text “My Awesome Theme” and if you take a look at the source code you should see a whole lot more. WordPress will also display the admin bar at the top of the page if you are logged in and a bunch of other things you don’t need to worry about at this stage.

The final piece of the puzzle is being able to add styles since our stylesheet is not loaded automatically. You may be used to adding styles in the head section when creating HTML websites. You should never do this in a theme – you should let WordPress handle this.

Create a functions.php file and add the following code:

Remember how I mentioned that WordPress injects functionality into themes and one of the places it does this is in the wp_head() function? Well, what we’re doing in the functions file is telling WordPress about our stylesheet, which in turn takes care of adding the appropriate code in the head section. The end result is exactly the same, but this method allows for much more flexibility, as you’ll see later.

For now, just save this as a snippet for future reference – in the following tutorials in this series, you’ll come to understand more about how all this works.

At this point, we have all the initial little bits and pieces in place. If you type something like body {background:red} in your stylesheet now, for instance, you’ll get a nice red background on your site.

Before moving on, let’s create a visual framework in which to work as well, a simple site title and a box, which will contain our content. Here’s what I’m thinking of:

Simple Theme
Simple and ugly, but it will do for now!

To make this work, I’ve added a title to the header file and I’ve opened a container. In the footer, I closed the container and added the footer copyright text. Finally, I added some styles to the stylesheet to make it look nice. Well, as nice as necessary at this stage of development, anyway.

Here are the three full files of code that make up the above website:

In addition, I added some dummy content to the index file – nothing special, just a header and a few paragraphs of lorem ipsum filler text wrapped in <p> tags.

Right now, any page you visit on your website will look the same because we only have an index.php file, which is the fallback for all pages.

Understanding the WordPress Loop

The loop is the heart of almost all pages in WordPress. The loop contains the content that is displayed on a page. WordPress knows what each page should contain, deriving all this from the URL. For example, a single post page should contain a single post, your home page should contain the ten most recent posts, a category archive page should include the 10 most recent posts in any given category, and so on.

This information is pulled from the database automatically, and all you need to do is “loop through” all the retrieved posts. It’s easier to show this than to explain it, so here’s how I would add it to the index file:

Once you have this in place, the magic of PHP, WordPress and themes becomes apparent. You’ll see a list of posts on your front page and if you add a post in the backend it will show up. If you click on the title, it will show a page with that single post shown, even though you haven’t created a special file for that single post.

Let’s analyze the code to see how it works.

It all starts with an if statement that checks the value of the have_posts() function. This function will return true if there are posts to show and false if there are no posts to show. As you can see from the else part of the statement, if there are no posts we display a quick message.

If there are posts, we create a while loop, which will be performed as long as have_posts() returns true. The first function that we use is the_post(), which sets up some post data for us (don’t worry about that yet) and advances the internal counter. If we are on the last post, this means that it will be displayed, but next time have_posts() will return false, which is how we end up eventually exiting the loop.

When displaying the post, I just added a title and the full content. I used the the_permalink() function to retrieve the URL of the post, the_title() to grab the title and the_content() to show the full content. These types of functions are called template tags in WordPress and they can be used within a loop and will detect the correct post as expected.

Here’s what my site looks like on the front-end so far:

Listing Posts
Listing Posts

From here on out, displaying posts in fancy ways is just a matter of knowing which functions in WordPress you can use and employing some CSS mastery. Here’s a handy list of template tag in the WordPress Codex you can use to output categories, tags, post dates, authors, featured images and oh-so-much more.

Templates and if Statements

So what would you do if you wanted to show an excerpt on the index page but the full content on a single page? You have two choices: use conditional tags or create a new template file.

Conditional tags can be used to check various things in WordPress, for example, if you are on a single page or not. Take a look at the full list of conditional tags in the WordPress Codex for more information.

With the help of the is_singular() tag we can do the following:

The other approach is to use two separate files: index.php would contain the variant that shows the excerpt and single.php would use the content. Go ahead and create single.php and use the the_content() in the loop there.

I hear you ask: which one is better? There’s no good answer to that question as it really depends on what you want to achieve. If all you’re changing between the single and index files is that one function, perhaps it would be better to use the if statement.

In reality, the single and list pages are usually different enough to warrant the two separate files, but there are good examples of themes that employ both techniques.

What many themes do is go one step further and create templates for the content within the loop. As you’ll see later, this makes our code much more readable and reusable.

Let’s look at a modified index file:

Ah, that’s better! First of all, I got rid of all the PHP opening and closing tags, which added a lot of clutter. But more importantly, I put all of the post content into different files. The get_template_part() function simply pulls in contents from a file and basically appends the second parameter to the first – adding a dash – to build a path.

In case of the second call in the else statement, the function would attempt to call template-parts/content-none.php. In the first instance, I left the second parameter empty and this would call template-parts/content.php.

In single.php, I would add the same code but add single as the second parameter of the get_template_part() function.

Finally, I would create the template-parts folder and the three files: content.php, none.php and content-single.php and paste the relevant code snippets there. For example, content.php would look like this:

Further Reading and Study

What we’ve covered in this tutorial is the basic gist of what it takes to create a very basic series of files to handle loops in WordPress. This will allow you to display your posts on your terms and with your styling.

This is just a glimpse of what’s to come! Check back here next week for part four in our series: WordPress Development for Beginners: Widgets and Menus.

But in the meantime, you should review last week’s post in this series, WordPress Development for Beginners: Learning PHP, to brush up on your PHP, as well as read through this article again thoroughly so you’re ready for next week’s installment.

Missed a tutorial in our beginners series? You can catch up on all five posts here:

Did you find this tutorial helpful? Why do you want to learn WordPress development? What do you want to know more about? Let us know in the comments below.