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.
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.
The simplest Theme possible is a child theme which includes only a style.css file, plus any images. This is possible because it is a child of another theme which acts as its parent.
In addition to CSS style information for your theme, style.css provides details about the Theme in the form of comments. The stylesheet must provide details about the Theme in the form of comments. No two Themes are allowed to have the same detailslisted in their comment headers, as this will lead to problems in the Theme selection dialog. If you make your own Theme by copying an existing one, make sure you change this information first.
Use valid CSS when possible. As an exception, use vendor-specific prefixes to take advantage of CSS3 features.
Minimize CSS hacks. The obvious exception is browsers-specific support, usually versions of IE. If possible, separate CSS hacks into separate sections or separate files.
All possible HTML elements should be styled by the Theme, both in post/page content and in comment content.
Tables, captions, images, lists, block quotes, et cetera.
Adding print-friendly styles is highly recommended.
You can include a print stylesheet with media=”print” or add in a print media block in your main stylesheet.
A theme can optionally use a functions file, which resides in the theme subdirectory and is named functions.php. This file basically acts like a plugin, and if it is present in the theme you are using, it is automatically loaded during WordPress initialization (both for admin pages and external pages). Suggested uses for this file:
Define functions used in several template files of your theme.
Set up an options menu, giving site owners options for colors, styles, and other aspects of your theme.
The default WordPress theme contains a functions.php file that defines many of these features, so you might want to use it as a model. Since functions.php basically functions as a plugin, the Function_Reference list is the best place to go for more information on what you can do with this file.
Templates are PHP source files used to generate the pages requested by visitors, and are output as HTML. Let’s look at the various templates that can be defined as part of a Theme.
WordPress allows you to define separate templates for the various aspects of your site. It is not essential, however, to have all these different template files for your site to fully function. Templates are chosen and generated based upon the Template Hierarchy, depending upon what templates are available in a particular Theme.
As a Theme developer, you can choose the amount of customization you want to implement using templates. For example, as an extreme case, you can use only one template file, called index.php as the template for all pages generated and displayed by the site. A more common use is to have different template files generate different results, to allow maximum customization.
Template Files List
Here is the list of the Theme files recognized by WordPress. Of course, your Theme can contain any other stylesheets, images, or files. Just keep in mind that the following have special meaning to WordPress — see Template Hierarchy for more information.
The main stylesheet. This must be included with your Theme, and it must contain the information header for your Theme.
The rtl stylesheet. This will be included automatically if the website’s text direction is right-to-left. This can be generated using the RTLer plugin.
The main template. If your Theme provides its own templates, index.php must be present.
The home page template, which is the front page by default. If you use a static front page this is the template for the page with the latest posts.
The single post template. Used when a single post is queried. For this and all other query templates, index.php is used if the query template is not present.
The single post template used when a single post from a custom post type is queried. For example, single-books.php would be used for displaying single posts from the custom post type books. index.php is used if the query template for the custom post type is not present.
The page template. Used when an individual Page is queried.
The date/time template. Used when a date or time is queried. Year, month, day, hour, minute, second.
The archive template. Used when a category, author, or date is queried. Note that this template will be overridden bycategory.php, author.php, and date.php for their respective query types.
The search results template. Used when a search is performed.
Attachment template. Used when viewing a single attachment.
Image attachment template. Used when viewing a single image attachment. If not present, attachment.php will be used.
The 404 Not Found template. Used when WordPress cannot find a post or page that matches the query.
These files have a special meaning with regard to WordPress because they are used as a replacement for index.php, when available, according to the Template Hierarchy, and when the corresponding Conditional Tag returns true. For example, if only a single post is being displayed, the is_single() function returns ‘true’, and, if there is a single.php file in the active Theme, that template is used to generate the page.
At the very minimum, a WordPress Theme consists of two files:
Both of these files go into the Theme directory. The index.php template file is very flexible. It can be used to include all references to the header, sidebar, footer, content, categories, archives, search, error, and any other page created in WordPress.
Or, it can be divided into modular template files, each one taking on part of the workload. If you do not provide other template files, WordPress may have default files or functions to perform their jobs. For example, if you do not provide a searchform.php template file, WordPress has a default function to display the search form.
Typical template files include:
Using these template files you can put template tags within the index.php master file to include these other files where you want them to appear in the final generated page.
The default files for some template functions may be deprecated or not present, and you should provide these files in your theme. As of version 3.0, the deprecated default files are located in wp-includes/theme-compat. For example, you should provide header.phpfor the function get_header() to work safely, and comments.php for the function comments_template().
For more on how these various Templates work and how to generate different information within them, read the Templatesdocumentation.
Custom Page Templates
The files defining each Page Template are found in your Themes directory. To create a new Custom Page Template for a Page you must create a file. Let’s call our first Page Template for our Page snarfer.php.
The above code defines this snarfer.php file as the “Snarfer” Template. Naturally, “Snarfer” may be replaced with most any text to change the name of the Page Template. This Template Name will appear in the Theme Editor as the link to edit this file.
The file may be named almost anything with a .php extension (see reserved Theme filenames for filenames you should not use; these are special file names WordPress reserves for specific purposes).
What follows the above five lines of code is up to you. The rest of the code you write will control how Pages that use the Snarfer Page Template will display. See Template Tags for a description of the various WordPress Template functions you can use for this purpose. You may find it more convenient to copy some other Template (perhaps page.php or index.php) to snarfer.php and then add the above five lines of code to the beginning of the file. That way, you will only have to alter the HTML and PHP code, instead of creating it all from scratch. Examples are shown below. Once you have created the Page Template and placed it in your Theme’s directory, it will be available as a choice when you create or edit a Page. (Note: when creating or editing a Page, the Page Template option does not appear unless there is at least one template defined in the above manner.)
To use the Template Hierarchy, you basically need to provide special-purpose Template files, which will automatically be used to override index.php. For instance, if your Theme provides a template called category.php and a category is being queried,category.php will be loaded instead of index.php. If category.php is not present, index.php is used as usual.
You can get even more specific in the Template Hierarchy by providing a file called, for instance, category-6.php – this file will be used rather than category.php when generating the page for the category whose ID number is 6. (You can find category ID numbers in Manage > Categories if you are logged in as the site administrator in WordPress version 2.3 and below. In WordPress 2.5 the ID column was removed from the Admin panels. You can locate the category id by clicking ‘Edit Category’ and looking on the URL address bar for the cat_ID value. It will look ‘…categories.php?action=edit&cat_ID=3′ where ’3′ is the category id). For a more detailed look at how this process works, see Category Templates.
If your Theme needs to have even more control over which Template files are used than what is provided in the Template Hierarchy, you can use Conditional Tags. The Conditional Tag basically checks to see if some particular condition is true, within the WordPress Loop, and then you can load a particular template, or put some particular text on the screen, based on that condition.
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_redirect action hook. More information about creating plugins can be found in the Plugin API reference.
Including Template Files
To load another template (other than header, sidebar, footer, which have predefined included commands like get_header()) into a template, you can use get_template_part(). This makes it easy for a Theme to reuse sections of code.
When developing Themes, it’s good to keep in mind that your Theme should be set up so that it can work well with any WordPress plugins users might decide to install. Plugins add functionality to WordPress via “Action Hooks” (see Plugin API for more information).
Most Action Hooks are within the core PHP code of WordPress, so your Theme does not have to have any special tags for them to work. But a few Action Hooks do need to be present in your Theme, in order for Plugins to display information directly in your header, footer, sidebar, or in the page body. Here is a list of the special Action Hook Template Tags you need to include:
Goes in footer.php, just before the closing </body> tag. Example plugin use: insert PHP code that needs to run after everything else, at the bottom of the footer. Very commonly used to insert web statistics code, such as Google Analytics.
Goes in comments.php directly before the file’s closing tag (</div>). Example plugin use: display a comment preview.
For a real world usage example, you’ll find these plugin hooks included in the default Theme’s templates.
Theme Customization API
As of WordPress 3.4, a new Theme Customization feature is available by default for nearly all WordPress themes. The Theme Customization admin page is automatically populated with options that a theme declares support for with add_theme_support() or using the Settings API, and allows admins to see non-permanent previews of changes they make in real time.
Theme and plugin developers interested in adding new options to a theme’s Theme Customization page should see the documentation on the Theme Customization API. Additional tutorials on the Theme Customization API are available at the Ottopress.com website.
You should escape dynamically generated content in your Theme, especially content that is output in HTML attributes. As noted inWordPress Coding Standards, text that goes into attributes should be run through esc_attr so that single or double quotes do not end the attribute value and invalidate the XHTML and cause a security issue. Common places to check are title, alt, and valueattributes.
Translation / i18n Support
To ensure smooth transition for language localization, use the gettext functions for wrapping all translatable text within the template files. This makes it easier for the translation files to hook in and translate the titles into the site’s language. See more atWordPress_Localization and i18n for WordPress Developers.
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.
The title should be plain text instead of a link pointing to itself.
Display the post date.
Respect date and time format settings unless it’s important to the design. (User settings for date and time format are in Settings > General.)
For output based on the user setting, use the_time( get_option( ‘date_format’ ) ).
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().
Author comment should be highlighted differently.
Display gravatars (user avatars) if appropriate.
Support threaded comments.
This file shouldn’t contain function defines unless in a 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 show the previous search term. 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 (echo or return the value). For example:
It’s a good practice to include the search form again on the results page. Include it with: get_search_form().
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. The recommended image size is 300×225.
When enabling an options page, use the edit_theme_options capability instead of switch_themes for options panels, unless the user actually should be able to switch Themes to be able to use your options panel. WordPress itself uses theedit_theme_options capability for menus, background, header, widgets, et cetera. See more at Roles and Capabilities andAdding Administration Menus.
A note about network mode and Theme options:
If you are using the edit_themes capability anywhere in your Theme, and the Theme is running on a network-enabled WordPress install (previously WordPress MU), be aware that the edit_themes capability used for accessing Theme options pages will prevent site admins in a network from seeing the options menu. Use edit_theme_options instead.
Theme Testing Process
Fix PHP and WordPress errors. Add the following debug setting to your wp-config.php file to see deprecated function calls and other WordPress-related errors: define(‘WP_DEBUG’, true);. See Deprecated Functions Hook for more information.