the red penguin

Creating a WordPress theme from scratch

1. Basic information

Before getting stuck into the build process, it’s important to know how WordPress themes work. If you’ve looked at any prebuilt theme, you’ll notice that it’s all contained in a folder, and there’s around 12 core files. Some themes, including the Default WordPress theme, include more files which allow extra customisation, but aren’t mandatory additions. Here’s an overview of the main files you’ll be working with:

style.css – All the styling for your theme goes here.
index.php – The core file that loads your theme, also acts as the homepage (unless you set your blog to display a static page).

header.php – Contains everything you’d want to appear at the top of your site.
sidebar.php – Contains everything you’d want to appear in a sidebar.
footer.php – Contains everything you’d want to appear at the bottom of your site.
archive.php – The template file used when viewing categories, dates, posts by author, etc.
single.php – The template file that’s used when viewing an individual post.
comments.php – Called at the bottom of the single.php file to enable the comments section.
page.php – Similar to single.php, but used for WordPress pages.
search.php – The template file used to display search results.
404.php – The template file that displays when a 404 error occurs.
functions.php – A file that can be used to configure the WordPress core, without editing core files.

Each of these files then contains a series of PHP template tags. These tags tell WordPress where to insert the dynamic content. A good example is the <?php the_title(); ?> tag, which pulls in the post title and displays it in your theme:

There’s stacks of template tags available, and more often than not there will be one that does exactly what you want – It’s just a case of finding it in the WordPress Codex. I’ve seen many themes that include some complicated PHP coding to achieve a function that’s already available as a simple template tag, so remember to browse the WordPress Codex whenever you’re stuck!

2. Configuring the stylesheet

Copy my stylesheet into style.css. Then at the top I need to put this comment:

Theme Name: Red Penguin
Theme URI:
Description: Every line written from scratch!
Version: 1.0
Author: Red Penguin
Author URI:

3. header.php

In here I need to paste the header from my static template, past the closing head tag and up to and including the div just before the content. I’ve added in some more comments and code too:

– a comment about where Google Analytics and Favicon code should go
– some php to create the page title dynamically
– this line to pick up the stylesheet:

<link rel="stylesheet" href="<?php echo get_template_directory_uri(); ?>/style.css" type="text/css" media="all" />

– this just before the closing head tag: ACTUALLY THIS CAUSES PROBLEMS SO I COMMENTED IT OUT

<?php wp_head();?>

so we have:

<!DOCTYPE html>

<!-- Google Analytics and Favicon info to go here -->

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="">
<link rel="preconnect" href="" crossorigin>
<link href="" rel="stylesheet">
<link href="" rel="stylesheet">
<link rel="stylesheet" href="<?php echo get_template_directory_uri(); ?>/style.css" type="text/css" media="all" />

if (trim($_SERVER['REQUEST_URI']) == "/") {
echo "<title>The Red Penguin</title>";
} else {
echo "<title>" . get_the_title() . " - The Red Penguin</title>";

<?php wp_head();?>


<div class="wholePage">

<div class="header">



<div class="menu">

Home About


<div class="content">

4. index.php

Create the index file. This can be just showing pages from the loop for now.



if ( have_posts() ) {

// Load posts loop.
while ( have_posts() ) {

echo '<h2><a href="';
echo '">';
echo "</a></h2>";

// older and newer links go here

} else {

echo "<h2>Nothing found</h2>";
echo "nothing at all";



5. Sidebar and footer

The header had everything up to and including the first content div, so in the footer we can post the end of that div and the rest of the template code.


<div class="footer">

(c) 2021 New website PLC





6. Creating the archive

The archive.php file is used to display a list of posts whenever they’re viewed by category, by author, by tag etc. It’s basically the same as the index file, but with the addition of a tag at the very top that renders a useful page title, so the user knows where they are. ‘Browsing the Articles category’ for instance.

// this is the bit I need to show the correct title for the archive page - I might not have done this for pfm
if (is_category()) { ?>
<h2><?php single_cat_title(); ?></h2>
<? } elseif (is_month()) { ?>
<h2><?php the_time(F, Y); ?></h2>
<? }

7. Constructing the page and single view

WordPress is made up of posts and pages. Posts use the single.php template file, whereas pages use the page.php template file. They’re pretty much the same, apart from that you tend to include the comments_template(); tag for posts, and not for pages.

That’s it mainly for the general construction of the theme.

8. Creating a 2 column template

Firstly I need a file called header-2.php. This can be exactly the same as header.php except for the last line. I need use to the leftbar class instead of the content one.

We’re going to have single.php as 2 column, so we need to change the first line of that file to this:

<?php get_header('2'); ?>

Now we can use sidebar.php! In that file paste the following code:


<div class="rightbar">

This is some info for the rightbar. This is some info for the rightbar. This is some info for the rightbar. <br /><br />
This is some info for the rightbar. This is some info for the rightbar. This is some info for the rightbar. <br /><br />
This is some info for the rightbar. This is some info for the rightbar. This is some info for the rightbar. <br /><br />

We need to ensure that sidebar is being used in single.php only for now. So go to all other .php pages and remove get_sidebar();

9. How to make the menu so that only admin can see it

In header and header-2 files:

$current_user = wp_get_current_user();

if ($current_user->ID == 1) {
echo '<div class="menu">HELLO PAUL! SECRET MENU!</div>';

>> Custom front page

I can now change index.php to read the following:




Welcome to the front door!




This is useful if I don’t want a ton of links on the front page just yet.

10. Creating an all posts page

Firstly, create a new page called All Posts, leave it blank and publish it.



Monday 25 October 2021, 515 views

Leave a Reply

Your email address will not be published. Required fields are marked *