Explanations and Examples

This section contains expanded explanations and examples for required items. This should be seen as a supporting document only to required items.

Code Code

Required: No PHP errors, warnings or notices

Themes must support PHP7. This means there must be no PHP errors, warnings or notices when running on PHP7. 

WordPress still supports lower PHP versions such as PHP 5.6 (read more). There should not be any PHP errors, warnings or notices if the theme is activated on a server with PHP 5.6.  Instead of downgrading the code to work for 5.6, the theme can include a PHP version check and deactivate the theme.

Required: Have a valid DOCTYPE declaration and include language_attributes.

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

Required: no shortcodes
The use of the add_shortcode() function is not allowed in themes as shown below:

add_shortcode( 'shortcode_name', 'shortcode_callback_func' );

Required: No removing or modifying non-presentational hooks.

remove_action( 'wp_head', 'wp_generator' );
remove_action( 'wp_head', 'feed_links_extra', 3); 
remove_action( 'wp_head', 'feed_links', 2); 

remove_action( 'admin_notices', 'update_nag', 3 );
remove_action( 'network_admin_notices', 'update_nag', 3 );

remove_filter( 'the_content','wpautop' );

add_filter( 'show_admin_bar', '__return_false' );

Top ↑

Core Functionality and Features Core Functionality and Features

Use get_template_directory() rather than TEMPLATEPATH to return the template path.

require_once( trailingslashit( get_template_directory() ) . 'inc/example.php' );

Use get_stylesheet_directory() rather than STYLESHEETPATH to return the stylesheet path.

require_once( trailingslashit( get_stylesheet_directory() ) . 'inc/example.php' );

This example should come with an additional warning to check if the file exists first if not used in a child theme.

Include comments_template().


Should be called in at least all singular views.

Top ↑

Plugin Territory Plugin Territory

Examples of plugin territory functionality:

  • Analytics or tracking support
  • SEO options
  • Contact forms
  • Non-design related meta boxes
  • Resource caching
  • Dashboard widgets in the admin area
  • Custom Post Types and Shortcodes
  • Social media “like”, “follow” and “share” buttons
  • Custom Gutenberg/Editor blocks
  • Custom image resizing
  • Default logo

Top ↑

  • be generic (solid color, gradient or patterns)
  • they can’t display logos
  • they can’t display text, only accepted form would be displaying the image size, `400x300px`
  • icons are allowed as long as they are not logos. A good example is a `photo camera` icon.
  • they need to be bundled within the theme, don’t use third party placeholder services directly (e.g: `placeholder.com`).

Top ↑

Documentation Documentation

Enough documentation should be provided so that the user can learn how to use theme specific options and templates.

Documenting and commenting your code will also make your theme easier to review. It is recommended that you follow the WordPress documentation standards.

Top ↑

Language Language

The text domain is required to be listed in the theme’s style.css head comment block. The text domain name should be generated from the theme slug. Example:

Theme Name: Mim's Debacle
Text Domain: mims-debacle

Theme authors have the choice of including their own language packs which will supersede the ones WordPress will self-install.
Here is an example how the text domain is loaded:

add_action( 'after_setup_theme', 'theme_review_setup' );
function theme_review_setup(){
    load_theme_textdomain( 'theme-slug', get_template_directory() . '/languages' );

For child themes loading the text domain would be:

add_action( 'after_setup_theme', 'theme_review_child_domain', 11 );
function theme_review_child_domain(){
    load_child_theme_textdomain( 'child-slug', get_stylesheet_directory() . '/languages' );

If a theme author chooses to include a POT file in their theme it needs to be kept up to date with all translation strings.

Top ↑

Stylesheets and Scripts Stylesheets and Scripts

All stylesheets must be enqueued with wp_enqueue_style. The following example is not allowed:

<link type="text/css" rel="stylesheet" href="" />

The correct way would be to call wp_enqueue_style() from a function that is hooked on the wp_enqueue_scripts action:

add_action( 'wp_enqueue_scripts', 'theme_review_css' );
function theme_review_css() {
    wp_enqueue_style( 'theme-style', get_stylesheet_uri() );

Printing internal styles using tags directly in the header.php is not allowed. The correct way would be to use a function that calls wp_add_inline_style and is hooked on the wp_enqueue_scripts action:

add_action( 'wp_enqueue_scripts', 'theme_review_styles' );
function theme_review_styles() {
        $custom_css = "
                        background: red;
        wp_add_inline_style( 'theme-style', $custom_css );

That would print the content of the $custom_css variable inside style tags directly after the stylesheet with the handle ‘theme-style’ is printed in the head.

All script files must be enqueued. The following example is not allowed:

echo get_template_directory_uri() . /js/theme-slider.js

The correct way would be to call wp_enqueue_style() from a function that is hooked on the wp_enqueue_scripts action:

add_action( 'wp_enqueue_scripts', 'theme_review_slider_options' );
function theme_review_slider_options(){
    wp_enqueue_script( 'theme-slider', get_template_directory_uri() . '/js/theme-slider.js', array( 'jquery' ) );
    wp_enqueue_script( 'theme-slider-init', get_template_directory_uri() . '/js/init.js', array( 'jquery', 'theme-slider' ) );
    // get user options
    $options = array();
    $options['autoplay'] = esc_attr( get_theme_mod( 'slider-autoplay', true ) );
    $options['navigation_style'] = esc_attr( get_theme_mod( 'nav-style', 'circles' ) );
    wp_localize_script( 'theme-slider-init', 'themeSliderOptions', $options );

Printing scripts using tags directly in templates is not allowed. The correct way would be to use a function that calls wp_add_inline_script and is hooked on the wp_enqueue_scripts action:

function theme_review_add_inline_script() {
wp_add_inline_script( 'theme-review-script', 
       $(document).ready(function() {
add_action( 'wp_enqueue_scripts', 'theme_review_add_inline_script' );

That would print the content of the $script variable inside script tags directly after the script with the handle ‘typekit’ is printed in the head or footer.

Top ↑

Themes are not allowed to have “obtrusive” upselling. The following are a few examples:

  • Notifications such as admin notices must be dismissable.
    • This means that the notices should not only be closed, but hidden permanently when the “Dismiss” link is closed.
  • Only one sub-page in addition to the TGMPA plugin installation page is allowed under the Appearance section in the admin sidebar.
  • Only one link on the top level in the customizer is allowed. This must be done using the customizer API(no injecting via JavaScript). Example. Further unobtrusive links are allowed in a separate section.
  • No options or panels/sections can be locked behind a paywall.
  • All settings in a theme must work.

As theme features for user social media:

  1. Social media links with icons settings are allowed.
  2. The simpler Social media sharing links that uses sharer.php? or similar are allowed.
  3. Social media “like” and “follow” buttons are not allowed.

The theme authors social media:

  1. Social media links are allowed.
  2. Social media “like”, “follow” and “share” buttons is not allowed.

Top ↑

Naming Naming

Child themes should not include the name of the parent theme unless the themes have the same author.

This requirement was put in place in order to prevent theme names like “Twenty Sixteen Child” and to protect theme authors.