WordPress Theme Development Quick Reference

WordPress is a free CMS and almost 30% of websites are designed by WordPress (WP). WordPress itself is CMS to manage content, but WordPress themes are responsible for the look of the website.

In this quick reference, we will develop a sample WordPress theme to learn how to create a custom WordPress theme.

WordPress theme development needs basic knowledge of HTML, CSS, JavaScript, and PHP.

Structure

Every WordPress themes, lives in “wp-content/themes“. If you visit this folder of your website, you can see there is at least one theme.

WordPress themes are hosted in this folder. Every theme has its own folders and files. Some files are WP pre-reserved files like “header.php, footer.php, etc”.

Every theme to function needs two files. The files are “index.php” and “style.css“. In style.css we will introduce our theme to WordPress and in index.php we will display our content with PHP codes.

Start WordPress theme development step by step

Go to the “wp-content/themes” of your WordPress website.

Create a new folder and name it “sample“.

Create “style.css” and “index.php” in the “sample” folder.

Open the style.css file and add the code.

/*
Theme Name: Sample
Theme URI: https://www.honarsystems.com/sample
Author: Honar Systems
Author URI: https://www.honarsystems.com/
Description: Sample is a WordPress theme
Version: 1.0.0
Tested up to: 5.8
Requires PHP: 5.6
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: sample
Tags: grid-layout, one-column, left-sidebar, right-sidebar, custom-background, custom-logo, custom-menu, featured-images, editor-style, translation-ready, footer-widgets, custom-colors, custom-header, theme-options, threaded-comments, blog, news
*/
  • Theme Name (Required): Name of the theme.
  • Theme URI: URI of the theme on your website
  • Author: Author name of the theme (Persion name or Company name)
  • Author URI: The author’s website
  • Description: Description of the theme
  • Version: Version of the theme
  • Tested up to: The minimum PHP version that we tested the theme
  • Requires PHP: The minimum PHP Version that the theme needs to run correctly
  • License: License of the theme. Every WordPress themes have GPL license. If you are creating a premium theme, you have to add a license in the theme root folder.
  • License URI: URl of the license
  • Text Domain: This is a text domain to tell WordPress to translate static texts in the theme.
  • Tags: The tags tell WordPress that we are using these features. If you upload your theme to WordPress.org, the theme will show when the user types the tags.

Go to “Appearance -> Themes” in your website Dashboard. Now you can see there is a Sample theme in the section. If you click the theme you will see the details of the theme.

 WordPress Theme Development

You have just created a WordPress theme. Now let’s go to develop the WordPress theme.

index.php

Open the index.php file and add the following code.

<?php
get_header();
if (have_posts()) {
    if (is_single()) {
        get_template_part('template-parts/content', 'single');
    } else {
        get_template_part('template-parts/content');
    }
} else {
    get_template_part('template-parts/content', 'none');
}
get_footer();

In this code, we used some functions that are WordPress functions to develop themes.

  • get_header: get header.php file content.
  • have_posts: check if WordPress has post to display.
  • is_single: check if client is seeing post or not.
  • get_template_part: include path codes.
  • get_footer: get footer content.

Now, let’s develop each file.

header.php

“header.php” is a reserved file name in WordPress to develop and contain header content of the website like head tag, meta tags and etc. header file contains every content that will include on every page of the website like the main menu, website logo, etc.

Create a “header.php” file in the root folder of the theme. Open the file and add the below code.

<!doctype html>
<html <?php language_attributes(); ?>>

<head>
    <meta charset="<?php bloginfo('charset'); ?>" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="profile" href="http://gmpg.org/xfn/11">
    <link rel="pingback" href="<?php bloginfo('pingback_url'); ?>">
    <?php wp_head(); ?>
</head>

<body <?php body_class(); ?>>
    <?php wp_body_open(); ?>
    <div id='page' class='site'>
        <a class='skip-link screen-reader-text' href='#content'>
            <?php esc_html_e('Skip to content', 'sample'); ?>
        </a>
        <button class='to-top' onclick='window.scrollTo({top: 0, behavior: "smooth"});'>
            <span class='dashicons dashicons-arrow-up-alt'></span>
        </button>

        <header class='site-header'>
            <div class="logo">
                <?php
                if (has_custom_logo()) :
                    the_custom_logo();
                else :
                    $blog_info    = get_bloginfo('name');
                    $description  = get_bloginfo('description', 'display');
                    $show_title   = (false === display_header_text());
                    $header_class = $show_title ? 'site-title' : 'screen-reader-text';
                ?>
                    <?php if ($blog_info) : ?>
                        <?php if (is_front_page() && !is_paged()) : ?>
                            <h1 class="<?php echo esc_attr($header_class); ?>">
                                <?php echo esc_html($blog_info); ?>
                            </h1>
                        <?php elseif (is_front_page() && !is_home()) : ?>
                            <h1 class="<?php echo esc_attr($header_class); ?>">
                                <a href="<?php echo esc_url(home_url('/')); ?>">
                                    <?php echo esc_html($blog_info); ?>
                                </a>
                            </h1>
                        <?php else : ?>
                            <h1 class="<?php echo esc_attr($header_class); ?>">
                                <a href="<?php echo esc_url(home_url('/')); ?>">
                                    <?php echo esc_html($blog_info); ?>
                                </a>
                            </h1>
                        <?php endif; ?>
                    <?php endif; ?>
                    <?php if ($description && $show_title) : ?>
                        <p class='site-description'>
                            <?php echo esc_html($description); ?>
                        </p>
                    <?php endif; ?>
                <?php endif; ?>
            </div>
            <div class="main-menu">
                <?php if (has_nav_menu('main-menu')) : ?>
                    <a class='mobile-btn' tabindex='0'>
                        <span class='dashicons dashicons-menu-alt3'></span>
                    </a>
                    <div class='main-nav'>
                        <div class='close' tabindex='0'><span class='dashicons dashicons-no-alt'></span></div>
                        <?php wp_nav_menu(array(
                            'menu' => 'main-menu',
                            'theme_location' => 'main-menu',
                            'menu_class' => 'menu',
                            'container' => 'ul'
                        ));
                        ?>
                    </div>
                <?php endif; ?>
            </div>
            <div class="search-box">
                <?php get_search_form(); ?>
            </div>
        </header>
        <main>

This code contains the head tag and website header. Website header contains website logo or name, Main menu, and search box.

<!doctype html>
<html <?php language_attributes(); ?>>

<head>
    <meta charset="<?php bloginfo('charset'); ?>" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="profile" href="http://gmpg.org/xfn/11">
    <link rel="pingback" href="<?php bloginfo('pingback_url'); ?>">
    <?php wp_head(); ?>
</head>

This code can be copied and pasted, because in almost every theme this code is the same.

You must add the wp_head() function after all codes inside the head tag.

After WordPress 5.2 every theme must have wp_body_open() function. This function is one of the most exciting features in WordPress is a simple function that fires an action. But this minor function has a huge impact on theme and plugin developers that inject code into WordPress themes.

Every standard theme should have the skip link to more accessibility to the content of the page.

<a class='skip-link screen-reader-text' href='#content'>
    <?php esc_html_e('Skip to content', 'sample'); ?>
</a>

Here we use the esc_html_e() function to make the text translatable to other languages. The “sample” word is the exactly same as the text domain in the style.css file we defined.

Back to Top button

This button is a tiny button in the corner of the page that if the user clicks it, he will go to the top of the page without scrolling.

<button class='to-top' onclick='window.scrollTo({top: 0, behavior: "smooth"});'>
    <span class='dashicons dashicons-arrow-up-alt'></span>
</button>

The onclick() function contains JavaScript code to scroll with a smooth move.

In this code, we use “Dashicons” of WordPress. If you logged in user you can see the icons in the front end, but other users can’t see them. You have to enqueue it in the functions.php file.

Header content

The header section contains the logo of the website if it has been set, if not, display the website title and description.

In this section, we used the_custom_logo() function and the menu. The logo and menu will be defined in the “functions.php” file.

We are going to develop a responsive WordPress sample theme, then we have to make everything responsive, especially the menus. Then we added the below elements to make it happen.

<a class='mobile-btn' tabindex='0'>
    <span class='dashicons dashicons-menu-alt3'></span>
</a>

and

<div class='close' tabindex='0'><span class='dashicons dashicons-no-alt'></span></div>

Both will be displayed in mobile mode. The first one will open the menu and the second one will close it.

searchform.php

As we told you, in WordPress theme development you have to avoid naming your files with pre-reserved names. The “searchform.php also is one of them.

In the header section we used get_search_form() function to display search box. This function displays WordPress inner search box by default but if you wanna create a custom search box in WordPress, you have to define it in the “searchform.php” file.

This file contains search box codes to modify the WordPress default search box.

Go to the root folder of your theme and create a “searchform.php” file. Open the file and add the following codes.

<?php
if (!defined('ABSPATH')) {
    exit;
}
?>
<div class="search-box-form">
    <form role="search" method="get" class="search-form" action="<?php echo esc_url(home_url("/")); ?>">
        <input type="search" placeholder="<?php esc_attr_e('Search', 'sample') ?>" class="search-field" value="<?php echo esc_attr(get_search_query()); ?>" name="s" />
        <button type="submit" tabindex="0" class="search-submit"><span class="dashicons dashicons-search"></span></button>
    </form>
</div>

With the below code you can ensure that the user can’t access directly to this file.

if (!defined('ABSPATH')) {
    exit;
}

The home_url() returns home page URL.

  • esc_attr_e() and esc_attr(): Attribute snitization. In esc_attr_e() you can add translatiable text and you don’t need echo.
  • esc_url(): URL sanitization.

Read more about data validation and sanitization here.

Style of the header

In WordPress theme development like other web pages development, HTML creates the structure and the CSS creates the look. We just created header HTML, now let’s design the look.

This is not WordPress theme development, this is WordPress theme designing.

Before going to add some CSS to our code, we have to enqueue our style to WordPress in the functions.php file.

After enqueueing the style, open the style.css file and add the following codes.

functions.php

This filename is pre-reserved too. We can say, this file is the heart of the functionality of the theme. We will define WordPress theme functionality in this file such as custom logo, link style, custom google font and etc.

if (!function_exists('sample_setup_logo')) {
    function sample_setup_logo()
    {
        add_theme_support(
            'custom-logo',
            array(
                'height' => 300,
                'width' => 250,
                'flex-width' => true,
                'flex-height' => true,
                'unlink-homepage-logo' => true,
            )
        );
    }
    add_action('after_setup_theme', 'sample_setup_logo');
}

Website title

if (!function_exists('sample_setup_title')) {
    function sample_setup_title()
    {
        add_theme_support('title-tag');
    }
    add_action('after_setup_theme', 'sample_setup_title');
}

Menu

if (!function_exists('sample_setup_menu')) {
    function sample_setup_menu()
    {
        register_nav_menus(
            array(
                'main-menu' => esc_html__('Main Menu', 'sample'),
                'bottom-social-menu' => esc_html__('Bottom Social Menu', 'sample'),
            )
        );
    }
    add_action('after_setup_theme', 'sample_setup_menu');
}

Dashicons

if (!function_exists('sample_enqueue_dashicons')) {
    function sample_enqueue_dashicons()
    {
        wp_enqueue_style('dashicons');
    }
    add_action('wp_enqueue_scripts', 'sample_enqueue_dashicons');
}

Enqueue Style

if (!function_exists('sample_enqueue_style')) {
    function sample_enqueue_style()
    {
        wp_enqueue_style('sample-style', get_stylesheet_uri());
    }
    add_action('wp_enqueue_scripts', 'sample_enqueue_style');
}

Enqueue Script

if (!function_exists('sample_enqueue_script')) {
    function sample_enqueue_script()
    {
        wp_enqueue_script('sample-script', get_template_directory_uri() . '/assets/js/custom.js', array('jquery'), '1.0.0', true);
    }
    add_action('wp_enqueue_scripts', 'sample_enqueue_script');
}

WordPress Theme Development

WordPress Development

Shopping Cart