Create a blank WordPress Theme

Creating a WordPress theme from scratch

Now that you have a basic understanding of what a WordPress theme is, we’re going to dive into creating your own WordPress theme.

When creating a WordPress theme, there a few things you need to have. As per our previous post, there are a few files that make a WP theme work: index, header, footer, sidebar, single and page. These files are the core files necessary to make sure your WP theme can render the most basic content.

It is important to note the modular layout of these files: index.php is actually comprised of header, footer, & sidebar. Single is for displaying posts and includes header, footer, and sidebar; same thing for page. If you fail to have these files in your theme, you will run into some problems rendering content.

There is a lot of PHP but the rest is html, css, and (maybe) javascript. So, get fancy if you want to!

As you create your first theme, you should notice that there is plenty of basic html code interspersed with php statements like this one:  <?php wp_title(); ?> that begin with <?php and end with ?> .  Everything between <?php  and  ?>  is php code and will be treated as such by the server. Everything else is html which is operated on by CSS and Javascript exactly as if the PHP was not present. In fact, the PHP code itself will also generate html which can be shaped by CSS and Javascript.

What this means for you, the developer, is that you can build your theme however you want to. For example, you may prefer to build your theme around a bootstrap theme that you like.  As long as you create the necessary set of php files as you are instructed in this tutorial, you should be fine. For your maiden voyage, you may prefer to strictly follow the instructions until you produce your first functional theme, but afterwards, go for it!

Step 1: Create your theme folder

In wp-content/themes, create a new folder called “LastnameFirstname-BlankTheme”. Enter that directory.
You have now created the folder where all your theme files will reside.

Step 2: header.php

Create a new file in your text editor, save it as “header.php” inside your theme folder.

Paste this code:

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
    <head>
        <meta charset="<?php bloginfo( 'charset' ); ?>">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="profile" href="http://gmpg.org/xfn/11">
        <title><?php bloginfo('name'); ?><?php wp_title(); ?></title>
        <?php wp_head(); ?>
    </head>
    <body <?php body_class(); ?>>
        <div id="wrapper">
            <div id="header">
                <h1><a href="<?php bloginfo('url'); ?>"><?php bloginfo('name'); ?></a></h1>
            </div>

So, with this file you are setting up basically the first 1/3 of your page. We have your DOCTYPE definition, all the way to the header which is the last div included in this file. This sets up everything up until the content.

Some notes:

We set the title of the page dynamically using:

<title><?php bloginfo('name'); ?><?php wp_title(); ?></title>

Bloginfo stores basic information about your blog, and ‘name’ is obviously the name of your blog, and wp_title is a function that displays the title of the current page. So you should see something like “My blog name | Home” in the title of your page on your browser window.

Note that we have not included a stylesheet – we will include this with our functions file.

The following is a vital function for your header.php file:

<?php wp_head(); ?>

This functions tells WP that this is where we want to call our scripts and styles. When we enqueue other additional styles/scripts this is where they will go. It is vital that this function is included right before the closing </head> tag.

The following is important for styling functions across WP:

<?php body_class(); ?>

This adds important classes to the <body> tag of every page. For instance, the home page will have the .home class by default. Every single page/post has its own ID in the format .page-id-{id} or .post-id-{id}. This allows you to target specific pages and make specific styling if you need to(very useful!).

This code sets up our actual page:

<div id="wrapper"> 
    <div id="header"> 
        <h1><a href="<?php bloginfo('url'); ?>"><?php bloginfo('name'); ?></a></h1>
    </div>

#wrapper is a div that will wrap all of our content, and #header stores all of our header content – in this case just our blog name linked to the homepage.
The header div will show our blog name on every single page and will provide a link to the homepage.

Notice we do not close #wrapper. You may think that this is not best practice, but in actuality the div is closed in one of our other files. Remember that this is just 1/3 of the page, and we need to set up the rest of the page in order to close #wrapper.

 

Step 3: index.php

Create a new file in your text editor, call it “index.php” and paste this code:

<?php get_header(); ?> 
<div class="container">   
    <?php if(have_posts()) : ?>
        <?php while(have_posts()) : the_post(); ?>      
            <div class="post" id="post-<?php the_ID(); ?>">     
                <h2>
                    <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">          
                        <?php the_title(); ?>
                    </a>
                </h2>    
                <div class="entry">              
                    <?php the_content(); ?>         
                    <p class="postmetadata"> 
                        <?php the_category(', ') ?><?php  the_author(); ?><br />         
                    </p>       
                </div><!-- end .entry -->     
            </div><!-- end .post -->   
        <?php endwhile; ?>    
    <?php endif; ?> 
</div><!-- end .container --> 
<?php get_sidebar(); ?> 
<?php get_footer(); ?>

 

This is an extremely dumbed-down version of a typical index.php, but it is purely for demonstration purposes. This file is responsible for rendering the content you see by default on the home page when you enable your theme. It would be different if you had a page set up to display as your home page, but we’re not going to be doing that for the purpose of this tutorial. Also I have provided some html comments so it’s easier to understand where each <div> ends.

Notes:

Notice the first line:

<?php get_header(); ?>

When you see this, think “header.php here”, as this calls the content of header.php to render as the first portion of this page. This allows the index.php file to focus only on the content that is displaying and how it is displaying.

The next important portion of this file is the inclusion of the loop:

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

The Loop extracts the data for each post from the WordPress database and inserts the appropriate information in place of each template tag. Any HTML or PHP code in The Loop will be processed for each post.

To put it simply, the Loop is true to its name: it loops through each post retrieved for the current page one at a time and performs the action specified in your theme.

Read more about the loop here if you are still lost: https://developer.wordpress.org/themes/basics/the-loop/

The loop is an extremely powerful mechanism as it allows you to create one block of styled elements for your posts, and then allows you to display as many posts as you want using those elements.

Also note the loop syntax: it starts with an IF and then has a WHILE included within it. If you are familiar with programming this should key you into why this function loops through each post.

Now that we are inside the loop, we are able to define some dynamic areas for all of our posts. Look at this:

<div class="post" id="post-<?php the_ID(); ?>">     
                <h2>
                    <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">          
                        <?php the_title(); ?>
                    </a>
                </h2>    
                <div class="entry">              
                    <?php the_content(); ?>         
                    <p class="postmetadata"> 
                        <?php the_category(', ') ?><?php  the_author(); ?><br />         
                    </p>       
                </div><!-- end .entry -->     
            </div><!-- end .post -->

What this says is I am creating a div for my posts with an id associated with that particular post’s id.
Next I am displaying the post’s title and linking it to the actual post.
Then I create another div with class entry – this will store my content.
Inside of the entry div, I have a function called the_content(). This function displays the content(i.e. the body text of the post) of each post in the loop.
Finally, for demonstration purposes, I have included the_category() and the_author() below the content. These functions will show the category and author of the posts, respectively.

As I mentioned before, this is the most barebones implementation possible. The important thing is to understand that inside the loop I can write some HTML and include some functions that will display information about each post, despite the fact that it’s only one block of code. If any of these concepts are uncomfortable, check out the link to the_loop’s documentation. WordPress has done a great job at creating extensive yet easy-to-understand documentation.

Step 4: footer.php
Create a new file called “footer.php” and add the following code:

            <div id="footer">  
                <p>
                    Copyright 2017 <a href="<?php bloginfo('url'); ?>"><?php bloginfo('name'); ?></a>
                </p>
            </div> <!-- end footer --> 
        </div> <!-- end wrapper --> 
    </body>
</html>

This is the file that gets called when we run the “get_footer” function you may have noticed in index.php. This file is pretty basic, as it’s just the content that we want in our footer(usually some contact info or copyright info), plus the end of our wrapper div. I have included some html comments for clarity.

Notice we have again called the bloginfo function and run some parameters through it to create a URL with our blog name on the front-end.

This is the most basic this file will get, but if you look through some other themes’ files they have very complex setups usually revolving around widget areas. This is not something we will cover in this tutorial, but there are plenty of tutorials out there about how to do this.

Step 5: sidebar.php
Create a new file called “sidebar.php” and include this code:

<?php
if ( ! is_active_sidebar( 'sidebar-1' ) ) {
    return;
} 
?>

<div id="sidebar">

    <?php dynamic_sidebar( 'sidebar-1' ); ?>

</div> <!-- end #sidebar -->

This code is responsible for creating the widget area for our sidebar. You may have noticed a lot of WordPress themes have sidebars with really cool content areas in them. These are all actually widgets that dynamically render content based on how that widget is set up.

In this file we first check to see if the sidebar is active, if it’s not we just return and render nothing. Else, we render the dynamic sidebar ‘sidebar-1’. Dynamic sidebar just means this div is a space that allows us to drop widgets into the area on the backend, and have them display on the frontend. After we finish this theme and enable it, you should be able to go to Appearance à widgets and add widgets to the sidebar-1 area.

At this point, we have create all the files we need to be able to display the home page: header, index, footer, sidebar. These are the core parts of our theme that make up the home page as well as the rest of our pages. However, we still need to create 2 more files to account for Posts and Pages because they have to be coded a specific way.

Step 6: single.php
Create a new file called “single.php” and add this code:

<?php get_header(); ?> 
<div class="container">   
    <?php if(have_posts()) : ?><?php while(have_posts()) : the_post(); ?>     
        <div class="post" id="post-<?php the_ID(); ?>">       
        <h2>
            <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">                        
                <?php the_title(); ?>
            </a>
        </h2>       
            <div class="entry">         
                <?php the_content(); ?>         
                <p class="postmetadata">
                    <?php the_category(', ') ?> <?php  the_author(); ?><br />        
                </p>       
            </div><!-- end entry -->         
        <?php endwhile; ?>     
        </div>  <!-- end post -->
    <?php endif; ?> 
</div><!-- end container --> 
<?php get_sidebar(); ?>
<?php get_footer(); ?>

This file is called single because it is the code for a single post. Each post is displayed using this template, and when you create a theme you should always use single.php to display individual posts. This is how WordPress renders posts, and without it you will run into errors.
You will notice a very similar syntax to index.php, which makes sense because we are writing a small amount of code that will be able to display any post. The real magic comes in because WP knows that single is for a single post, and because it knows that it will only use this page to display one post at a time. That being said, we still need to code it to be able to work for any post. Thus, we have the above code. I won’t go in-depth as it follows the same rules as index.php, so if you are lost just look back to that section.

Step 7: page.php
Create a new file called “page.php” and insert the following code:

<?php get_header(); ?>  
<div class="container">  
    <?php if(have_posts()) : ?><?php while(have_posts()) : the_post(); ?>   
        <div class="post">     
            <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>   
            <div class="entry">     
                <?php the_content(); ?>    
            </div> <!-- end entry -->
        <?php endwhile; ?>  
    </div><!-- end post -->
    <?php endif; ?> 
</div><!-- end container -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>

If you understood the last section, this will be even easier: it’s the same thing just for pages. There are two main content types in WordPress: Posts & Pages. Posts would be things like blog posts, and pages would be things like a contact us page. Both are accessible and editable in similar ways in the editor, but can potentially be rendered in completely different ways. Thus, WordPress required us to include separate files for them in our themes.

Step 8: functions.php
Create a new file and call it “functions.php”, insert the following code:

<?php
/** 
 * Enqueue scripts and styles. 
 */
function my_scripts() {        
    wp_enqueue_style( 'themename-style', get_stylesheet_uri() );
} 
add_action( 'wp_enqueue_scripts', 'my_scripts' ); 

//Register Sidebar
if ( function_exists('register_sidebar') ) {    
    register_sidebar();
}
?>

Functions.php is a vital file for your theme, as it allows you to queue up scripts, create dynamic functions for your theme, or make small tweaks via php on the fly. In this basic implementation we are enqueuing our scripts via an “action” that calls our function my_scripts. This registers our style.css file that we will create in the next step. If you wanted to include more stylesheets you would do it in this function as well. Additionally we let wordpress know we have a sidebar via the register_sidebar function.

Step 9: style.css
Create a new file “style.css” and add this code:

/*

Theme Name: LastnameFirstname-BlankTheme

Theme URI: http://example.com

Author: Your name

Author URI: http://example.com

Description: Description

Version: 1.0.0

*/

body {
    background-color: #D4D8D9;
    color: #333;
    }

This is our styles for the entire theme. This is the file called when we run get_stylesheet_uri() in functions.php because wordpress knows to look for a file called style.css by default. Also, you will notice a block of comments at the top of this file. You must include this block, and you must change it to reflect the proper information based on your theme. WordPress parses this information when trying to set up and display your theme. If it is wrong or missing you will run into errors. I have also included some basic styling for the body just for demonstration purposes. Feel free to include some more styling based on the classes and ID’s we have defined earlier.

Step 10: Upload and enable
You have now created the necessary files to display the most minimal of WordPress themes. Upload the files you have created to your theme folder on the server, and navigate to Appearance --> themes. You should see your theme as an option. Click enable, and go to the home page. You should now see your basic theme implemented.

It should look something like this: http://apdemo.mynmi.net/

The only way to go from here is up! Mess around and experiment and try to get some stuff displaying in a custom way that deviates from this basic tutorial.