Codex

Interested in functions, hooks, classes, or methods? Check out the new WordPress Code Reference!

Theme Development

This article is about developing WordPress Themes. If you wish to learn more about how to install and use Themes, review Using Themes. This topic differs from Using Themes because it discusses the technical aspects of writing code to build your own Themes rather than how to activate Themes or where to obtain new Themes.

Why WordPress Themes

WordPress Themes are files that work together to create the design and functionality of a WordPress site. Each Theme may be different, offering many choices for site owners to instantly change their website look.

You may wish to develop WordPress Themes for your own use, for a client project or to submit to the WordPress Theme Directory. Why else should you build a WordPress Theme?

  • To create a unique look for your WordPress site.
  • To take advantage of templates, template tags, and the WordPress Loop to generate different website results and looks.
  • To provide alternative templates for specific site features, such as category pages and search result pages.
  • To quickly switch between two site layouts, or to take advantage of a Theme or style switcher to allow site owners to change the look of your site.

A WordPress Theme has many benefits, too.

  • It separates the presentation styles and template files from the system files so the site will upgrade without drastic changes to the visual presentation of the site.
  • It allows for customization of the site functionality unique to that Theme.
  • It allows for quick changes of the visual design and layout of a WordPress site.
  • It removes the need for a typical WordPress site owner to have to learn CSS, HTML, and PHP in order to have a great-looking website.

Why should you build your own WordPress Theme? That's the real question.

  • It's an opportunity to learn more about CSS, HTML, and PHP.
  • It's an opportunity to put your expertise with CSS, HTML, and PHP to work.
  • It's creative.
  • It's fun (most of the time).
  • If you release it to the public, you can feel good that you shared and gave something back to the WordPress Community (okay, bragging rights)

Theme Development Standards

WordPress Themes should be coded using the following standards:

Anatomy of a Theme

WordPress Themes live in subdirectories of the WordPress themes directory (wp-content/themes/ by default) which cannot be directly moved using the wp-config.php file. The Theme's subdirectory holds all of the Theme's stylesheet files, template files, and optional functions file (functions.php), JavaScript files, and images. For example, a Theme named "test" would reside in the directory wp-content/themes/test/. Avoid using numbers for the theme name, as this prevents it from being displayed in the available themes list.

WordPress includes a default theme in each new installation. Examine the files in the default theme carefully to get a better idea of how to build your own Theme files.

For a visual guide, see this infographic on WordPress Theme Anatomy.

WordPress Themes typically consist of three main types of files, in addition to images and JavaScript files.

  1. The stylesheet called style.css, which controls the presentation (visual design and layout) of the website pages.
  2. WordPress template files which control the way the site pages generate the information from your WordPress database to be displayed on the site.
  3. The optional functions file (functions.php) as part of the WordPress Theme files.

Let's look at these individually.

Child Themes

This section has moved to the Theme Developer Handbook: https://developer.wordpress.org/themes/advanced-topics/child-themes/

Theme Stylesheet

This section has moved to the Theme Developer Handbook: https://developer.wordpress.org/themes/basics/main-stylesheet-style-css/

Functions File

This section has moved to the Theme Developer Handbook: https://developer.wordpress.org/themes/basics/theme-functions/

Template Files

This section has moved to the Theme Developer Handbook: https://developer.wordpress.org/themes/basics/template-files/

Custom Page Templates

This section has moved to the Theme Developer Handbook: https://developer.wordpress.org/themes/template-files-section/page-template-files/#creating-custom-page-templates-for-global-use

Query-based Template Files

This section has moved to the Theme Developer Handbook: https://developer.wordpress.org/themes/template-files-section/taxonomy-templates/

Defining Custom Templates

It is possible to use the WordPress plugin system to define additional templates that are shown based on your own custom criteria. This advanced feature can be accomplished using the "template_include" action hook. More information about creating plugins can be found in the Plugin API reference.

Including Template Files

This section has moved to the Theme Developer Handbook: https://developer.wordpress.org/themes/template-files-section/partial-and-miscellaneous-template-files/

Referencing Files From a Template

This section has moved to the Theme Developer Handbook: https://developer.wordpress.org/themes/functionality/media/

Plugin API Hooks

This section has moved to the Theme Developer Handbook: https://developer.wordpress.org/themes/advanced-topics/plugin-api-hooks/

Theme Customization API

This section has moved to the Theme Developer Handbook: https://developer.wordpress.org/themes/customize-api/

Untrusted Data

This section has moved to the Security page in the Common APIs Handbook: https://developer.wordpress.org/apis/security/


Translation Support / I18n

To ensure smooth transition for language localization, use the WordPress gettext-based i18n functions for wrapping all translatable text within the template files. This makes it easier for the translation files to hook in and translate the labels, titles and other template text into the site's current language. See more at WordPress Localization and I18n for WordPress Developers.

Theme Classes

Implement the following template tags to add WordPress-generated class attributes to body, post, and comment elements. For post classes, apply only to elements within The Loop.

Template File Checklist

When developing a Theme, check your template files against the following template file standards.

Document Head (header.php)

  • Use the proper DOCTYPE.
  • The opening <html> tag should include language_attributes().
  • The <meta> charset element should be placed before everything else, including the <title> element.
  • Use bloginfo() to set the <meta> charset and description elements.
  • Use Automatic Feed Links to add feed links.
  • Add a call to wp_head() before the closing </head> tag. Plugins use this action hook to add their own scripts, stylesheets, and other functionality.
  • Use the Title_Tag theme feature to set the <title> element within wp_head().
  • Do not link the theme stylesheets in the Header template. Use the wp_enqueue_scripts action hook in a theme function instead.

Here's an example of a correctly-formatted HTML5 compliant head area:

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
    <head>
        <meta charset="<?php bloginfo( 'charset' ); ?>" />
        <link rel="profile" href="http://gmpg.org/xfn/11" />
        <link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>" />
        <?php if ( is_singular() && get_option( 'thread_comments' ) ) wp_enqueue_script( 'comment-reply' ); ?>
        <?php wp_head(); ?>
    </head>

Navigation Menus (header.php)

  • The Theme's main navigation should support a custom menu with wp_nav_menu().
    • Menus should support long link titles and a large amount of list items. These items should not break the design or layout.
    • Submenu items should display correctly. If possible, support drop-down menu styles for submenu items. Drop-downs allowing showing menu depth instead of just showing the top level.

Widgets (sidebar.php)

  • The Theme should be widgetized as fully as possible. Any area in the layout that works like a widget (tag cloud, blogroll, list of categories) or could accept widgets (sidebar) should allow widgets.
  • Content that appears in widgetized areas by default (hard-coded into the sidebar, for example) should disappear when widgets are enabled from Appearance > Widgets.

Footer (footer.php)

  • Use the wp_footer() call, to appear just before closing body tag.
<?php wp_footer(); ?>
</body>
</html>

Index (index.php)

  • Display a list of posts in excerpt or full-length form. Choose one or the other as appropriate.
  • Include wp_link_pages() to support navigation links within posts.

Archive (archive.php)

  • Display archive title (tag, category, date-based, or author archives).
  • Display a list of posts in excerpt or full-length form. Choose one or the other as appropriate.
  • Include wp_link_pages() to support navigation links within posts.

Pages (page.php)

  • Display page title and page content.
  • Display comment list and comment form (unless comments are off).
  • Include wp_link_pages() to support navigation links within a page.
  • Metadata such as tags, categories, date and author should not be displayed.
  • Display an "Edit" link for logged-in users with edit permissions.

Single Post (single.php)

  • Include wp_link_pages() to support navigation links within a post.
  • Display post title and post content.
    • The title should be plain text instead of a link pointing to itself.
  • Display the post date.
  • Display the author name (if appropriate).
  • Display post categories and post tags.
  • Display an "Edit" link for logged-in users with edit permissions.
  • Display comment list and comment form.
  • Show navigation links to next and previous post using previous_post_link() and next_post_link().

Comments (comments.php)

  • Author comment should be highlighted differently.
  • Display gravatars (user avatars) if appropriate.
  • Support threaded comments.
  • Display trackbacks/pingbacks.
  • This file shouldn’t contain function definitions unless in the function_exist() check to avoid redeclaration errors. Ideally all functions should be in functions.php.

Search Results (search.php)

  • Display a list of posts in excerpt or full-length form. Choose one or the other as appropriate.
  • The search results page shows the search term which generated the results. It's a simple but useful way to remind someone what they just searched for -- especially in the case of zero results. Use the_search_query() or get_search_query() (display or return the value, respectively). For example:
    <h2><?php printf( __( 'Search Results for: %s' ), '<span>' . get_search_query() . '</span>'); ?></h2>
  • It's a good practice to include the search form again on the results page. Include it with: get_search_form().

JavaScript

This section has moved to the Theme Developer Handbook: https://developer.wordpress.org/themes/basics/including-css-javascript/

Screenshot

Create a screenshot for your theme. The screenshot should be named screenshot.png, and should be placed in the top level directory. The screenshot should accurately show the theme design and saved in PNG format. While .jpg, .jpeg, and .gif are also valid extensions and file formats for the screenshot, they are not recommended.

The recommended image size is 1200px wide by 900px tall. The screenshot will usually be shown smaller but the over-sized image allows for high-resolution viewing on HiDPI displays. Note that because the Manage Themes screen is responsive, the top and bottom of the screenshot image might not be viewable so keep graphics near the center.

Theme Options

Themes can optionally support the Theme Customize Screen. For an example code, see A Sample WordPress Theme Options Page.

When enabling the availability of the Theme Customize Screen for a user role, use the "edit_theme_options" user capability instead of the "switch_themes" capability unless the user role actually should also be able to switch the themes. See more at Roles and Capabilities and Adding Administration Menus.

If you are using the "edit_themes" capability anywhere in your Theme to gain the Administrator role access to the Theme Customize Screen (or maybe some custom screens), be aware that since Version 3.0, this capability has not been assigned to the Administrator role by default in the case of WordPress Multisite installation. See the explanation. In such a case, use the "edit_theme_options" capability instead if you want the Administrator to see the "Theme Options" menu. See the additional capabilities of Administrator role when using WordPress Multisite.

Theme Testing Process

This section has moved to the Theme Developer Handbook: https://developer.wordpress.org/themes/advanced-topics/theme-testing/

Resources and References

Code Standards

Theme Design

CSS

Templates

Functions listing

Testing and QA

Release & Promotion