-
Notifications
You must be signed in to change notification settings - Fork 0
Part 1: Building A WordPress Theme
Hello and welcome to the Building a WordPress Theme tutorial! You'll learn how to build a basic WordPress theme from scratch to use on your own blog or website. Let's get started!
We're going to upload a blank(ish) WordPress theme to our website in our set up of our local environment. To get the files for this, just go to https://github.com/CalumChilds/your-wp-theme/archive/refs/heads/main.zip. Don't extract the .zip file, as you'll be uploading it to WordPress later on. Make sure you rename the zip file to your-wp-theme.zip.
We'll be using Local to create a local WordPress environment on our computer. This means you'll be able to run WordPress without having to worry about web servers or hosting fees!
Make sure you've downloaded and installed this software at https://localwp.com, then do the following:
- Click the + button on the bottom-left to create a local website.
- Select the "Create a new site" option, then click "Continue".
- Enter your website's name. This can be anything you want. Then click "Continue".
- Keep the "Preferred" option selected and press "Continue".
- For the username and password, use something simple that you'll remember (such as admin) for both the username and password. (When creating live WordPress websites, do make sure you set the username to something than admin and choose a strong password with letters, numbers and special characters.)
- Once you're done, click "Add Site".
Local will now create a local WordPress website. If you get any notifications about privileges being required (usually titled "Host Redirection"), just click on them and press "Yes".
Once the website is set up, select the "WP Admin" button (circled below:)
Then enter your username and password. You'll then be redirected to this page. Hover over "Appearance", then click on "Themes".
Next to the "Themes" heading, click the "Add New" button:
Then next to the "Add Themes" heading, click the "Upload Theme" button:
Click Browse, then select the your-wp-theme.zip file we downloaded earlier and upload it.
You should see something that looks like this. Click "Activate" to activate the theme onto your website.
Go to the front page of your website where you should see a blank white screen. Don't worry about it! (there's a white screen because there isn't any PHP code in our theme yet!)
To get to your theme's code, open Locals and click the "Open Site Folder" button, as shown below:
Then navigate to the app/public/wp-content/themes/your-wp-theme folder.
Note: If you're using Windows, you can get straight to the folder by clicking the list of folders at the top of your screen then copying the path above (app/public/...). Or you can click through to the directory - up to you!
WordPress is built using PHP and mySQL, but in recent years it has used React for the editor used to change posts and pages.
All WordPress themes must have these two files: index.php
and style.css
.
We will need more files than just these two, but the files we need are in the theme we just uploaded.
Next up, we'll be looking at the CSS of the theme and how you can customise it.
Open the theme's style.css
file. At the top of the file, you'll see a comment that looks like this:
/*
Theme Name: Your WordPress Theme
Theme URI: http://yourwebsite.com/
Author: Your Name
Author URI: http://yourwebsite.com/
Description: This is your WordPress theme.
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: LICENSE
Text Domain: your-wp-theme
*/
The above CSS comment has to appear at the top of the theme's style.css
file. It tells WordPress information about the theme and the people that made it. Feel free to change any of the default information.
Note: If you change the text domain, make sure to replace your-wp-theme with your own text domain in this tutorial.
This theme is designed so you can change the colours and fonts it uses easily just by changing a few lines of the CSS code. We're going to do this using CSS variables. We'll define them like this:
:root {
--font-family: 'Arial', sans-serif;
--background-colour: white;
--main-colour: #111111;
--paragraph-colour: #111111;
--link-colour: blue;
}
You'll see how this comes in handy as we build our WordPress theme.
Before we start writing the theme files, we need to let WordPress know what features our theme supports. To do this, we need to create a your_wp_theme_setup()
method in functions.php
like this (you don't have to write the comments if you don't want to:)
<?php
function your_wp_theme_setup() {
// Add default posts and comments RSS feed links to <head>
add_theme_support( 'automatic-feed-links' );
// Lets WordPress generate the <title> tag value for us
add_theme_support( 'title-tag' );
// Lets WordPress know that our theme allows us to add a featured image for each post/page
add_theme_support( 'post-thumbnails' );
// This theme uses wp_nav_menu() in one location.
register_nav_menus(
array(
'menu-1' => esc_html__( 'Primary', 'your_wp_theme' ),
)
);
// Adds support for HTML5 elements
add_theme_support(
'html5',
array(
'search-form',
'comment-form',
'comment-list',
'gallery',
'caption',
'style',
'script',
)
);
add_theme_support('responsive-embeds');
add_theme_support( 'customize-selective-refresh-widgets' );
// Lets WordPress add CSS styling for Gutenberg block elements in our theme
add_theme_support( 'wp-block-styles' );
add_theme_support('custom-header');
}
add_action( 'after_setup_theme', 'your_wp_theme_setup' );
Now we've done that, let's tell WordPress how to display our content!
First, we need to tell WordPress how we want to display content on the following page types:
- blog posts
- static pages
- home page
- search results
So let's get started!
Firstly, we need to display the header and footer on all our pages. There are two built-in functions that allow us to do this: get_header()
(which will get our theme's header.php
file and output it's contents) and get_footer()
(which will get our theme's footer.php
file and output it's contents.)
In all of your theme's .php files (except for functions.php
, header.php
and footer.php
) enter this code into your files:
<?php get_header(); ?>
<?php get_footer(); ?>
Extra info: If you want to have multiple headers or footers in your theme (such as a different header for your home page or a different footer for your about page), you could declare your header function as get_header('home')
which would get the header-home.php
file if it existed and the default header file (header.php
) if if didn't.
Then go into your header.php
file and enter this code:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="<?php echo get_stylesheet_directory_uri(); ?>/style.css">
<script src="<?php echo get_stylesheet_directory_uri(); ?>/script.js" type="text/javascript"></script>
<?php wp_head(); ?>
</head>
<body>
<nav id="site-navigation" class="main-navigation">
<button class="menu-toggle" aria-controls="primary-menu" aria-expanded="false">Menu</button>
<?php
wp_nav_menu(
array(
'theme_location' => 'menu-1',
'menu_id' => 'primary-menu',
)
);
?>
</nav>
The wp_head()
function acts as a hook for plugins and core WordPress functions to add stylesheets and scripts to the website.
The wp_nav_menu()
function gets the items in the primary menu.
Now go into your footer.php
file and enter this code:
<footer>
<?php dynamic_sidebar('footer'); ?>
<p>© <?php bloginfo('name'); ?> 2023 All Rights Reserved</p>
<?php wp_footer(); ?>
</footer>
</body>
</html>
Here's what the functions in this code are doing:
- the
wp_footer()
function is similar to thewp_head()
function, except it's for the footer. It should always be placed before the</body>
tag. - the
bloginfo('name')
function gets the website's name. - the
dynamic_sidebar('footer')
function gets the footer widget and displays it here
We just need to register the footer widget we just created in our functions.php
file within our your_wp_theme_setup
method, like this:
register_sidebar(
array(
'name' => esc_html__('Footer','your_wp_theme'),
'id' => 'footer-widgets',
'description' => esc_html__('Add footer blocks here', 'your_wp_theme'),
'before_widget' => '<section id="%1$s class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h2 class="widget-title">',
'after_title' => '</h2>',
)
);
Once you've saved that, at the top of your website, click the "Customize" button, which should take you to a screen that looks like this:
Click the "Widgets" option and then click the square + button to add a block. There are a wide variety of blocks you can add - pick a few and see what they do!
If you're creating a blog, you'll want all your blog posts to be displayed on the front page of the website. The code that displays each blog post is called The Loop. Below is an example of a list of blog posts being displayed on a WordPress website:
To do this, go to index.php
and on the line after the get_header()
function, create an if statement like this:
<?php
<?php get_header(); ?>
<h1 class="site-title align-center">Welcome to <?php bloginfo('name'); ?>!</h1>
<h2 class="site-tagline align-center"><?php bloginfo('description'); ?></h2>
<?php
if ( have_posts() ) :
while ( have_posts() ) :
the_post();
?>
<div class="post">
<h2 class="post-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<p class="post-excerpt"><?php the_excerpt(); ?></p>
<a class="button" href="<?php the_permalink(); ?>">Read more...</a>
</div>
<?php endwhile; ?>
<?php endif; ?>
<?php get_footer(); ?>
There's several functions in The Loop. Here's what each of them do:
-
have_posts()
checks to see if there are any posts -
the_post()
iterates the post ID that's being displayed in the loop -
the_title()
gets the post's title -
the_excerpt()
gets a preview of the blog post (usually the first 50 characters, but you can manually change the excerpt of a post if you wanted to) -
the_permalink()
gets the blog post's URL
Next up, we're going to be displaying individual posts and pages on our website.
Extra info: index.php
is the default file used if WordPress can't find a template for what it's displaying in your theme (such as a blog post or page).
To display posts and pages differently, we'll need to use two different templates: single.php
and page.php
. The single.php
template dictates how a blog post will be displayed. The page.php
template dictates how pages are displayed.
Extra info: If there isn't a page.php
template but there is a single.php
template, it will use single.php
to display the page.
In the single.php
file, write this code on the line after the get_header()
function:
<?php
while ( have_posts() ):
the_post();
?>
<h1 class="post-title"><?php the_title(); ?></h1>
<p align="center"><?php echo get_the_date(); ?> | <?php the_category(', '); ?></p>
<?php the_content(); ?>
<?php endwhile; ?>
<?php the_post_navigation(); ?>
Here's what each of those functions that we haven't seen already do:
-
the_content()
gets the post or page's content -
get_the_date()
gets the date the blog post was published -
the_category()
gets all the categories that the blog post is part of and separates them with a comma and a space (', ') -
the_post_navigation()
displays links to the previous and next posts
The code in page.php
is roughly the same as above, but with a few minor changes, as you'll see below:
<?php
while ( have_posts() ):
the_post();
?>
<h1 class="page-title"><?php the_title(); ?></h1>
<p align="center"><?php echo get_the_date(); ?></p>
<?php the_content(); ?>
On some websites, for whatever reason, you want a custom home page rather than a list of blog posts. WordPress allows you to define this in your theme relatively easily in the front-page.php
file!
For our search results page, we'll use the same code as we did for index.php
. The only difference will be that we'll display "Here's what we found for (search query)" if we find any results and "We couldn't find anything for (search query)" if we didn't.
Go into the search.php
file and enter this code:
<?php get_header(); ?>
<?php
if ( have_posts() ) : ?>
<h1 class="page-title">Here's what we found for "<?php the_search_query(); ?>"</h1>
<?php
while ( have_posts() ) :
the_post();
?>
<div class="post">
<h2 class="post-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<p class="post-excerpt"><?php the_excerpt(); ?></p>
<a class="button" href="<?php the_permalink(); ?>">Read more...</a>
</div>
<?php endwhile; ?>
<?php else: ?>
<h1 class="page-title">We couldn't find anything for "<?php the_search_query(); ?>".</h1>
<p class="align-center">Consider changing your query and trying again.</p>
<?php get_search_form(); ?>
<?php endif; ?>
<?php get_footer(); ?>
And that's it, you've built your first WordPress theme! Feel free to change the default colours and font using the CSS variables at the top of style.css
.
If you want to do some more work on your WordPress theme, have a look at the extension tasks below:
There are over 60,000 WordPress plugins that you can install! Have a look and install some plugins that you like the look of (but don't install anything with WooCommerce in the name just yet, we'll be doing that next!)
Note: When you're creating your own WordPress websites, only install and activate plugins that are absolutely necessary. The more plugins you have, the slower your website will be and the more security vulnerabilities there could be in your website.
Most WordPress themes that are used on websites are on the WordPress Theme Directory. Using the WordPress Theme Developers Handbook and other resources, try to make your theme ready to be released into the WordPress Theme Directory.