Do’s and Don’ts of WordPress Theme Development 

Ulrich Pogson

Theme Reviewer on WordPress.org

Development Envoirment

Enable WP_DEBUG

style.css

/*
Theme Name: _s
Theme URI: http://underscores.me/
Author: Automattic
Author URI: http://automattic.com/
Description: Hi. I'm a starter theme called <code>_s</code>,
or <em>underscores</em>, if you like. I'm a theme meant for 
hacking so don't use me as a <em>Parent Theme</em>. Instead 
try turning me into the next, most awesome, WordPress theme 
out there. That's what I'm here for.
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: _s
Tags: black, blue, brown, gray, three-columns, featured-images,
accessibility-ready, translation-ready
*/

Readme/License

Don't...

...release a theme without a license

 

Do...

...define the theme license

...make a note of the resources used in the theme.(License of assets - Fonts, CSS, JS, Images, PHP, etc)

PHP Prefixing

PHP function names

function _s_setup() { }


PHP class names

class _s_Setup { }

PHP global variables

global $_s_variable;

 

PHP constants

_S_VERSION

WordPress Prefixing

Action/Filter hooks

apply_filters( '_s_content_width', 640 );


Script/Style handles

wp_enqueue_style( '_s-style' );


Image size names

add_image_size( '_s-large', '800', '400' );

Breaking the rules

  • Third-party script/style handles
  • Third-party PHP scripts/libraries
  • Standard Image sizes

WP Standard Handles


// Scripts
wp_enqueue_script( 'jquery-fitvids', get_template_directory_uri()
 . '/js/jquery.fitvids.js', array( 'jquery' ), '1.1.1', true );

// Function and Classes
class TGM_Plugin_Activation { ... }

// Custom image size
add_image_size( '910x460-crop', 910, 460, true );

Settings

Don't...

...save every single option as a single row

 

Do...

...a single array for all the options

...use sane defaults

Sanitizing

// Customizer
$wp_customize->add_setting(
    'twitter_url',
    array(
        'default'           => 'https://twitter.com/grapplerulrich',
        'transport'         => 'postMessage',
        'sanitize_callback' => 'esc_url_raw',
    )
);

// Settings API
register_setting(
    '_s_options_group',
    '_s_options',
    '_s_sanitize_settings'
);

Escaping

// Insecure
echo get_theme_mod( 'twitter_url' );

// Secure
echo esc_url( get_theme_mod( 'twitter_url' ) );


$_s_options = get_option( '_s_options' );
echo esc_url( $_s_options['twitter_url'] );

Use Core Features

Use the functions, actions and filters that WordPress core provides

Don't reinvent the wheel

Plugin Territory

Themes are presentation not functionality

Functionality

Chose a theme on it's design not it's features

Contact forms

SEO Settings

Small improvements to WordPress

Content

Where is my content after switching themes?

Shortcodes

Custom Post Types

Non presentational metadata

Content

Don't...

...include custom widgets that save content

...save content in the theme settings

 

Do...

...use WordPress features like Sidebars, Pages and Menus

Internationalization

Create a POT file

Define the Text Domain in the Style.css

Use the same text domain as the theme slug

Checklist

  • Have I defined the licences correctly?
  • Is my code prefixed correctly?
  • Are you saving the settings correctly?
  • Is my code fully sanitized and escaped?
  • Is there a WordPress method that I could use instead?
  • Is my code translation-ready?
  • Is my theme only presentational?

Resources

Made with Slides.com