How to Structure a WordPress Theme

by Ry on July 7, 2016

I’ve been a PHP developer for over a decade and this blog theme is my first WordPress project. The theme is called Beltway Dragon and the source code is available on GitHub.

First let me tell you what the theme does and then I will get into the coding structure. The theme only uses two pages; there is a home page with paginated blog posts and there is a single post page that shows the respective post, the comments and a comment form. So at this point it’s basically a minimum blog.

Now let’s get into the coding structure. For HTML I use a template that is a full HTML document. For example, a template.php could look like:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8"/>
        <?wp_head()?>
        <?=$t_head?>
    </head>
    <body>
        <div id="header">header</div>
        <div id="content"><?=$t_content?></div>
        <div id="footer">footer</div>
        <?wp_footer()?>
    </body>
</html>

You can use WordPress functions in your template and I also like to use PHP variables as you can see with $t_head and $t_content. You should also put any other static HTML into the template that needs to be on all pages – like metadata, the visual header, sidebar and visual footer.

Here is how we use the template in index.php or any other top-level template file:

<?php

$t_head = '<link rel="stylesheet" href="' .
    get_template_directory_uri() .
    'index.css"/>';

$t_content = 'my content';

include get_template_directory() . 'template.php';

You can see that we are using $t_head to insert a CSS file and we are using a small phrase as our content. If you need to assign something significant to a template variable, then use a function. For example, a function for blog home page content might look like:

<?php

namespace myns;

function home_content() {
    ob_start();

    while(have_posts()) {
        the_post(); ?>

        <div class="blog-post">
            <h2><a href="<?the_permalink()?>"><?the_title()?></a></h2>
            <div class="post-info"><?the_date()?> by <?the_author()?></div>
            <?the_content()?>
        </div> <?php
    }

    return ob_get_clean();
}

In index.php we can now use this:

$t_content = myns\home_content();

Do not put your HTML functions in the WordPress functions.php file. Instead put them in a separate file, namespace them and composer autoload them. Also, your HTML functions should return HTML not echo HTML.

To recap HTML, we use template files with full HTML documents and all other HTML comes from functions that return HTML.

We’ve talked about HTML, now let’s setup the CSS. I like to use one shared CSS file that is included on all pages in addition to a separate CSS file for each page. To include the same CSS file on all pages you can put this in your WordPress functions.php file:

add_action(
    'wp_enqueue_scripts',
    function() {
        wp_enqueue_style(
            'shared',
            get_template_directory_uri() .
                'shared.css');
    });

To include a separate CSS file on each page you can use $t_head to insert a CSS file as we did above.

And that is all; that is how I structure my WordPress theme. I may update this post later with improvements. For my next WordPress personal project I want to do a forum or a shopping cart.