WordPress Themes

Developing WordPress Themes:
the essentials

Presented by Mike Little (mikelittle.org / @mikelittlezed1)
(first presented at Havas Lynx July 2016)

Mike Little

Mike Little
WordPress co-founder.
WordPress Specialist.

@mikelittlezed1
https://mikelittle.org/
https://linkedin.com/in/MikeLittle

Agenda

WordPress architecture

The template hierarchy

The event model

Actions and filters

The right time to use plugins

What's wrong with page builders

Starter themes and Frameworks

WordPress architecture

WordPress is a content management system (CMS) written in PHP and JavaScript.

It uses a MySQL database for written content storage and configuration data.

Images and other uploaded media are stored on the filing system.

WordPress architecture

All the code sits on top of a web server: Apache and Nginx being the most common. Though it runs under others including Microsoft's web server IIS.

WordPress architecture

The code is split into three main parts: The core code, a theme (sometimes two), and zero or more plugins.

WordPress architecture

The core code is further split into general purpose Application Programming Interfaces (APIs) and function librararies, adminstration and CMS interface, and a small number of entry points (php scripts).

Request Processing

The processing that results from a request from a user's browser is logically straightforward.

But it can get complex in the details.

Request Processing: URLs

http://example.com/
http://example.com/about/
http://example.com/2016/06/30/my-post
http://example.com/category/football
http://example.com/tag/rooney
http://example.com/author/mikelittle
http://example.com/feed/
http://example.com/product/cheese-fancies
http://example.com/movie/star-wars/
http://example.com/character/luke
http://example.com/genre/sci-fi

Request Cycle

The request cycle basically proceeds as follows:

  • Request comes from browser via web server
  • WP parses the URL
  • Decides what DB query to run
  • Retrieves the data
  • Hands it off to the theme

Theme Structure

Minimum requirements for a theme: style.css and index.php

/*
Theme Name: Twenty Sixteen
Theme URI: https://wordpress.org/themes/twentysixteen/
Author: the WordPress team
Author URI: https://wordpress.org/
Description: Twenty Sixteen is a modernized take on an ever-popular WordPress layout...
Version: 1.2
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: black, blue, ... one-column, two-columns, responsive-layout, accessibility-ready
Text Domain: twentysixteen

This theme, like WordPress, is licensed under the GPL.
Use it to make something cool, have fun, and share what you've learned with others.
*/						

Theme Structure

The index.php file can include everything you need to do. The header, footer, sidebar, and main loop.

However, it is prudent to split the common parts into separate files to be included in other template files.

So header.php, footer.php, and sidebar.php are common partials. There are WordPress functions to pull them in.

Code structure

The basic content of index.php


<?php get_header(); ?>
    
<?php if ( have_posts() ) : ?> <?php // Start the loop. while ( have_posts() ) : the_post(); get_template_part( 'template-parts/content' ); // End the loop. endwhile; endif; ?>
<?php get_sidebar(); ?> <?php get_footer(); ?>

Content partial

A typical content partial

>
<?php the_title( sprintf( '

', esc_url( get_permalink() ) ), '

' ); ?>
<?php twentysixteen_post_thumbnail(); ?>
<?php the_content( sprintf( __( 'Continue reading "%s"', 'twentysixteen' ), get_the_title() ) ); ?>
<?php twentysixteen_entry_meta(); ?>

Other template files

If the request is for a page, WordPress will look for page.php. You can display a page slightly differently.

If it is for a category archive it will look for a template called category.php

There is a whole hierarchy of templates you can use.

Template Hierarchy

Mike Little

Template hierarchy

Body Class

If you only want to style the content differently, not change the layout; you can use one or more of the classes WordPress adds to the body tag.

<body class="page page-id-2 page-template-default">
<body class="single single-post postid-11 single-format-standard">
<body class="archive category category-uncategorized category-1 hfeed">
<body class="home blog hfeed">

Child Themes

Child themes allow you to create a theme that inherits everything from a parent theme, but which allows you to override the CSS and one or more of the template file or partials.

Any theme can be a parent theme.

To create a child theme simply add one extra item to the style.css header comment:

/*
Theme Name: My Twenty Sixteen Child
Template: twentysixteen
*/						

Functions

One last file you can add to a theme: functions.php

This file is loaded early in the request process, before the url parsing takes place.

Functions.php can include:

  • Theme intitialisation,
  • Theme support functions,
  • Admin screens,
  • Hooks to change the behaviour of WordPress itself, or any of the plugins, or the parent theme.
  • Pretty much anything!

The event Model

WordPress does not use a Model, View, Controller (MVC) architecture.

Instead, it implements an event driven architecture.

At various places throught the process of executing a request, WordPress triggers events known as Actions.

A theme or plugin can hook onto those events and have it's own code executed at that point.

Further, some of the events are implemented as Filters. A theme or plugin can hook into the data or configuration that WordPress is currently handling and change it.

The event Model

The hooks, Actions and Filters, are chainable. More than one set of code can hook onto the same event or filter.

There is a prority system.

Much of WordPress' functionality is hooked into it's own event model.

As there is an ability to remove a hook, you can change behavior by simply unhooking WordPress' or a plugin's hooks.

Actions and Filters

Actions are triggered by specific events that take place in WordPress, such as publishing a post, changing themes, or displaying an administration screen.

An Action is a custom PHP function defined in your plugin or theme and hooked, i.e. set to respond, to these events. Actions typically do one or more of the following:

  • Modify database data.
  • Send an email message.
  • Modify the generated administration screen or front-end page sent to a user browser.
  • Authenticate a user.

Actions and Filters

A filter on the other hand, when triggered is passed one or more pieces of data by WordPress. The hooked function can choose to modify, remove, or add to that data before returning it to WordPress. Typical filters include:

  • the_content - modify the content of a post or page
  • the_title - modify the title of a post or page
  • content_save_pre - modify the content of a post before it is written to the DB.
  • posts_where - modify the query WordPress uses to retreive data.
  • authenticate - authenticate a user

The Right Time to use Plugins

As anything can be added to a theme's functions.php, you could implement any functionality.

But you really shouldn't.

Restrict the functionality in functions.php to code that implements:

  • Theme support functions
  • Theme initialisation
  • Code to modify the query behaviour that your theme needs. eg. request 9 posts on a product page
  • Code to add specific admin screens to configure your theme

The Right Time to use Plugins

Anything else should be put in a plugin.

Portfolio custom post types

Sliders/carousels

Shopping baskets

If it's storing data/content, or vital functionality would be missing if the users changes theme, then it should not be in the theme.

What's wrong with Page Builders

Some themes implement drag and drop page builders.

These are often implemented as 'shortcodes'.

When a user changes their theme, they are left with pages full of shortcodes the new theme does not know how to render.

What's wrong with Page Builders

There are some plugins that implement drag and drop page builders.

These are also often implemented as 'shortcodes'.

Slightly better, but if an update, or an out of memory error, breaks the plugin, you are still left with pages full of shortcodes.

One exception I know of is Beaver Builder. It renders the html when you save. So if the plugin breaks, you still have some semblance of real content.

Starter Themes and Frameworks

Starting a theme from scratch is not recommended.

Better might be to use one of the many "starter" or "skeleton" themes. E.g. Underscores (http://underscores.me/), Bones (http://themble.com/bones/) or Roots (https://roots.io/)

Starter Themes and Frameworks

Theme frameworks are a popular option too.

These are parent themes, and you implement a child theme. Overriding styles, templates and functionality as required.

Populer ones include: Genesis Framework (https://www.studiopress.com/), Theme Hybrid (http://themehybrid.com/hybrid-core), or Headway (http://headwaythemes.com/)

Themes Frameworks

Theme frameworks, often have lots of functionality and flexibility built in.

Most will have their own Actions and Filters.

So you can change the behavior from functions.php.

Or even install a plugin that enhances the functionality of the theme framework.

Some code tips

Enqueue your style sheets and javascript

<?php
function twentysixteen_scripts() {
    // Add custom fonts, used in the main stylesheet.
    wp_enqueue_style( 'twentysixteen-fonts', twentysixteen_fonts_url(), array(), null );
    // Theme stylesheet.
    wp_enqueue_style( 'twentysixteen-style', get_stylesheet_uri() );
    // Load the Internet Explorer specific stylesheet.
    wp_enqueue_style( 'twentysixteen-ie', get_template_directory_uri() . '/css/ie.css', array( 'twentysixteen-style' ), '20160412' );
    wp_style_add_data( 'twentysixteen-ie', 'conditional', 'lt IE 10' );
    // Load the html5 shiv.
    wp_enqueue_script( 'twentysixteen-html5', get_template_directory_uri() . '/js/html5.js', array(), '3.7.3' );
    wp_script_add_data( 'twentysixteen-html5', 'conditional', 'lt IE 9' );
}
?>

Some code tips

Keep your Head simpe

<!DOCTYPE html>
<html <?php language_attributes(); ?> class="no-js">
<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">
    <?php if ( is_singular() && pings_open( get_queried_object() ) ) : ?>
    <link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
    <?php endif; ?>
    <?php wp_head(); ?>
</head>

Some code tips

You can implement different versions of the standard files

<?php
get_header( 'home' );
get_sidebar( 'shop' );
get_footer( 'author' );

Some code tips

You Should Validate, Sanitise, and Escape all the things.

<?php // Validate
$order_quantity = intval( $_POST['order_quantity'] );
if ( ! $order_quantity ) {
  $order_quantity = '';
}

Some code tips

You Should Validate, Sanitise, and Escape all the things.

<?php
// Sanitise
$title = sanitize_text_field( $_POST['title'] );
update_post_meta( $post->ID, 'title', $title );

sanitize_title()
sanitize_title_for_query()
sanitize_title_with_dashes()
?>

Some code tips

You Should Validate, Sanitise, and Escape all the things.


// Escape

<?php echo esc_html( $title ); ?>

Click me

codex: Validating Sanitizing and Escaping User Data

Learning Resources

Recently published review: 7 Courses That Turn WordPress Users into Developers (Free and Paid Options)

Recommended: Know the Code

Recommended: JavaScript for WordPress

Thank You

Mike Little
@mikelittlezed1
https://mikelittle.org/
https://linkedin.com/in/MikeLittle