WordPress: desarrollo de themes

[Fuente: http://codex.wordpress.org/Theme_Development]

El porqué de WordPress Themes

Los WordPress Themes son un conjunto de ficheros que juntos crean el diseño y la funcionalidad de una web hecha con WordPress. Cada Theme puede ser distinto, ofreciendo muchas posibilidades para los propietarios de una web para poder cambiar instantanemente el look del site.

Puedes querer programar los WordPress Themes para tu propio uso, para el proyecto de un cliente o para subirlo al WordPress Thme Directory. ¿Por qué querrias construir un WordPress Theme?

  • Para crear un look uniforme a tu web en WordPress.
  • Para tener las ventajas de templates , template tags y el WordPress Loop para generar distintos resultados y looks en la web.
  • Para proporcionar templates alternativos para caracteristicas especificas, como por ejemplo las páginas de categoria y páginas de resultados.
  • Para rápidamente cambiar entre dos templates , o aprovechar el Theme or style siwtcher que permite a los propietarios del site cambiar el look de la web.

Un WordPress theme tiene muchos beneficios también:

  • Separa los estilos de presentación y ficheros de template del resto de ficheros del sistema asi que la web se actualizará sin cambios drásticos cuando cambiemos su presentación visual.
  • Permite la personalización de la funcionalidad del site unico para ese Theme
  • Permite cambios rápidos del diseño visual y layout de una web hecha con WordPress
  • Elimina la necesidad de que el propietario de la web tenga que aprender CSS, HTML y PHP y poder tener una web con un aspecto visual avanzado.

¿Por qué querrias hacer tu propio WordPress Theme? Esa es la cuestión importante.

  • Es una oportunidad para aprender más sobre CSS, HTML y PHP
  • Es una oportunidad para hacerte experto en CSS, HTML y PHP
  • Es creativa
  • Es divertido (la mayor parte del tiempo)
  • Si tu haces público el Theme, la satisfacción de hacer algo por la comunidad WordPress.

Desarrollo de Themes estandar

Los WordPress Themes deben ser programados siguiendo los siguientes estandars:

Anatomía de un Theme

Los WordPress Themes viven en subdirectorios que residen en wp-content/themes/. El subdirectorio de un Theme contiene todos los ficheros de estilos , ficheros del template , y ficheros de funciones opciones (functions.php) , ficheros Javascript , e imagenes. Por ejemplo, un Theme llamado “test ” estaría en el directorio wp-content/themes/test/. Intenta no poner números al nombre del theme, ya que esto le impide salir en la lista de themes disponibles.

WordPress incluye un theme por defecto en cada nueva instalación. Examina los ficheros por defecto con cuidado para tener una mejor idea de como haremos nuestros prorios Theme files.

Para una guia visualFor a visual guide, see this infographic: http://yoast.com/wordpress-theme-anatomy/

Los WordPress Themes tipicamente se componen de tres tipos de ficheros, aparte de imagenes y ficheros Javascript. Una es el stylesheet llamado style.css, el cual controla la presentación (diseño visual  y layout) de las páginas web. El segundo es el fichero opcional de funciones functions.php . Los otros ficheros son los ficheros de template que controlan la forma en que las páginas del site generan la información desde la BBDD de WordPress para ser mostrada en el site. Es lo que vamos a examinar a continuación.

Un Child Theme

Un Child Theme es el theme más simple posible .Incluye solo el fichero style.css, más alguna imagen. Esto es posible porque es hijo de otro theme que actua como su padre.Para más info sobre ellos ver  Child Themes or this great tutorial by op111.

La Theme Stylesheet (la CSS)

Además de información de estilo para el thme , style.css proporciona detalles sobre el Them en la forma de comentarios. El stylesheet debe proporcionar detalles sobre el Theme en la forma de comentarios. No se permite que dos Themes tengan los mismos detalles listados en los comentarios de cabecera, ya que esto lleva a problemas en el dialogo  de selección de Theme. Si haces tu propio Theme copiando uno existente, asegurate de cambiar esta información primero.

Los siguiente es un ejemplo de las primeras lineas del CSS del Theme “Twenty Ten”:

/*

Theme Name: Twenty Ten
Theme URI: http://wordpress.org/
Description: The 2010 default theme for WordPress.
Author: wordpressdotorg
Author URI: http://wordpress.org/
Version: 1.0
Tags: black, blue, white, two-columns, fixed-width, custom-header, custom-background, threaded-comments, sticky-post, translation-ready, microformats, rtl-language-support, editor-style, custom-menu (optional)

License:
License URI:

General comments (optional).
*/

Estas lineas de comentarios del style.css son requeridas para que el WordPress sea capaz de identificar y mostrarlo en la panel de Administracion como un theme disponible junto con el resto de los que haya instalados.

Guias de diseño de un hoja de estilo

Sigue los CSS coding standards cuando construyas el CSS.

  • Utiliza CSS válido siempre que puedas. Como excepción, utiliaz prefijos especificos de navegador para conseguir ventajas del CSS3
  • Minimiza los CSS hacks salvo cuando son para cosas especificas que ofrece un navegador en concreto.
  • Todos los posibles elementos HTML deben ser dado estilo por el Theme , tanto en el contenido ya sea pagina o post y en el contenido del comentario.
    • Tables, captions, images, lists, block quotes, et cetera.
  • Añade estilos printer-friendly es altamente recomendado.
    • Se puede incluir un print stylesheet con media=”print” o añadir un bloqye de print media en tu CSS principal.

Fichero Functions

Un Theme puede opcionalmente utilizar un fichero functions, que reside en la carpeta del theme y se llama functions.php. Este fichero basicamente  actua como un plugin, y si está presente en el theme que estás utilizando, automaticamente es cargado durante la inicializacion de WordPress (tanto en las páginas de administración como en las páginas externas). Los usos sugeridos para este fichero son:

El tema por defecto que viene con WordPress contiene un functions.php que define muchas de estas caracteristicas, asi que puedes querer utilizarlo como modelo. Ya que functions.php básicamente funciona como un plugin , la Function_Reference es el mejor lugar para tener más información sobre qué se puede hacer con este fichero.

Ficheros de Template

Los ficheros de template son ficheros con codigo fuente PHP utilizados para generar las páginas pedidas por los visitantes, y su salida es HTML. Veamos todos los ficheros de este tipo que se pueden definir.

WordPress te permite definir ficheros de template separados para los distintos aspectos de la web. No es esencial, sin embargo, tener todos estos ficheros de template para que el theme funcione. Los ficheros de template son elegidos y generados basandose en la Template Hierarchy (son como piezas de un puzzle).

Como programador de Themes, puedes decidir la cantidad de personalizacion que quieres utilizando estos ficheros de template. Por ejemplo , como caso extremo, puedes utilizar uno solo , el index.php como el template para todos los posts y pages generados por la web. Lo más comun es tener varios ficheros de template que generan resultados diferentes , para asi permitir una mejor personalización.

Lista de Ficheros de Template

Presentamos a continuación una lista de los ficheros de template reconocidos por WordPress. Desde luego, tu propio Theme puede contener otros ficheros de CSS, images, js. Solo ten en cuenta que estos tienen significado especial para WordPress.

  • style.css
    • The main stylesheet. This must be included with your Theme, and it must contain the information header for your Theme.
  • rtl.css
    • The rtl stylesheet. This will be included automatically if the website direction is RTL. you can generate it using a plugin called the RTLer.
  • index.php
    • The main template. If your Theme provides its own templates, index.php must be present.
  • comments.php
    • The comments template.
  • front-page.php
  • home.php
    • 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.
  • single.php
    • 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.
  • single-<post-type>.php
    • The single post template used when a single post from a custom post type is queried. For example, single-books.phpwould be used for displaying single posts from the custom post type booksindex.php is used if the query template for the custom post type is not present.
  • page.php
    • The page template. Used when an individual Page is queried.
  • category.php
  • tag.php
  • taxonomy.php
    • The term template. Used when a term in a custom taxonomy is queried.
  • author.php
  • date.php
    • The date/time template. Used when a date or time is queried. Year, month, day, hour, minute, second.
  • archive.php
    • The archive template. Used when a category, author, or date is queried. Note that this template will be overridden bycategory.phpauthor.php, and date.php for their respective query types.
  • search.php
    • The search results template. Used when a search is performed.
  • attachment.php
    • Attachment template. Used when viewing a single attachment.
  • image.php
    • Image attachment template. Used when viewing a single image attachment. If not present, attachment.php will be used.
  • 404.php
    • The 404 Not Found template. Used when WordPress cannot find a post or page that matches the query.

Estos ficheros tienen un significado especial para WordPress porque son utilizados como sustitución de index.php cuando están presentes, siempre de acuerdo a la Template Hierarchy, y cuando la correspondiente Conditional Tag retorna true. Por ejemplo, si estamos visualizando un post simple , entonces la funcion is_single() retorna true, y , si hay un archivo llamado single.php , entonces será el archivo template utilizado para mostrar esa página.

Ficheros de Template Básicos

Como mínimo , un Theme de WordPress se compone de dos ficheros:

  • style.css
  • index.php

Ambos ficheros residen en el directorio del Theme.El archivo index.php es muy flexible. Puede ser utilizado para incluir todas las referencias al header, sidebar, footer, content, categories, archives, search, error, y cualquier otra pagina creado en WordPress.

O puede ser dividido en ficheros de template tipo modulo, cada una cogiendo una parte del workload. Si no pones ningun otro fichero de template , WordPress utilizará un de la version por defecto. Por ejemplo, si no tienes un archivo de template comments.php, WordPress automaticamente utilizará wp-comments.php.

Los ficheros de template más típicos son:

  • comments.php
  • footer.php
  • header.php
  • sidebar.php

Utilizando estos ficheros de template puedes poner template tags dentro del index.php para hacer que se incluyan en las páginas generadas:

Here is an example of the include usage:

<?php get_sidebar(); ?>

<?php get_footer(); ?>

For more on how these various Templates work and how to generate different information within them, read theTemplates documentation.

Ficheros de Template para personalizar las Pages

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. At the top of the snarfer.php file, put the following:

<?php
/*
Template Name: Snarfer
*/
?>

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 notuse; 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 alterthe 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.)

Ficheros de Template Query-based

WordPress can load different Templates for different query types. There are two ways to do this: as part of the built-inTemplate Hierarchy, and through the use of Conditional Tags within The Loop of a template file.

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 ManageCategories 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.

For example, to generate a distinctive stylesheet in a post only found within a specific category, the code might look like this:

<?php
if ( is_category( '9' ) ) {
    get_template_part( 'single2' ); // looking for posts in category with ID of '9'
} else {
    get_template_part( 'single1' ); // put this on every other category post
}
?>

Or, using a query, it might look like this:

<?php
$post = $wp_query->post;
if ( in_category( '9' ) ) {
    get_template_part( 'single2' );
} else {
    get_template_part( 'single1' );
}
?>

In either case, this example code will cause different templates to be used depending on the category of the particular post being displayed. Query conditions are not limited to categories, however, see the Conditional Tags article to look at all the options.

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 likeget_header()) into a template, you can use get_template_part(). This makes it easy for a Theme to reuse sections of code.

Referenciar ficheros desde un archivo de template

When referencing other files within the same Theme, avoid hard-coded URIs and file paths. Instead reference the URIs and file paths with bloginfo().

Note that URIs that are used in the stylesheet are relative to the stylesheet, not the page that references the stylesheet. For example, if you include an images/ directory in your Theme, you need only specify this relative directory in the CSS, like so:

h1 {
    background-image: url(images/my-background.jpg);
}

Plugin API Hooks

Cuando se están programando Thmes , es bueno recordar que tu tema debe estar configurado de forma que funcione bien con cualquier plugin de WordPress que los usuarios decidan instalar. Los plugins añaden funcionalidad a WordPress a través de lo que se llama “Action Hooks“.

La mayoria de los Actions Hooks están dentro del código PHP core de WordPress , asi que tu Theme no tiene que tener ninguna tag especial para que estos funcionen. Pero unos pocos Action Hooks necesitan estar presentes en tu Theme, para cuando queremos que los Plugins muestren informacion directamente en tu header, footer, sidebar o el body de la pagina. Veamos una lista de tags especiales de Action Hooks que necesitarias incluir:

wp_head()

Goes in the <head> element of a theme, in header.php. Example plugin use: add JavaScript code.
wp_footer()
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.
wp_meta()
Typically goes in the <li>Meta</li> section of a Theme’s menu or sidebar; sidebar.php template. Example plugin use: include a rotating advertisement or a tag cloud.
comment_form()
Goes in comments.php directly before the comment form’s closing tag (</form>). Example plugin use: display a comment preview. As of WordPress 3.0, you should use the default comment form instead, see comment_form().

For a real world usage example, you’ll find these plugin hooks included in the default Theme’s templates.

Untrusted Data

You should escape dynamically generated content in your Theme, especially content that is output in HTML attributes. As noted in WordPress 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 titlealt, and value attributes.

In a few cases there might already be a template tag for common cases where safe output is needed. One such case involves the “title” attribute when used with the_title() for post and page titles. To avoid a security vulnerability, usethe_title_attribute() instead. Here’s an example of correct escaping for the title attribute in a post title link when using translatable text:

<?php echo esc_attr( sprintf( __( 'Permanent Link to %s', 'theme-name' ), the_title_attribute( 'echo=0' ) ) ); ?>

Replace deprecated escape calls with the correct calls: wp_specialcharshtmlspecialchar with esc_htmlclean_url withesc_url, and attribute_escape with esc_attr. See Data_Validation for more.

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 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 “content-type” meta element should be placed before everything else, including the title element.
  • Use bloginfo() to fetch the title and description.
  • Use automatic feed links to add feed links.
  • Add a call to wp_head(). Plugins use this action hook to add their own scripts, stylesheets, and other functionality.

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

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>" />
<title><?php wp_title(); ?> <?php bloginfo( 'name' ); ?></title>
<link rel="profile" href="http://gmpg.org/xfn/11" />
<link rel="stylesheet" href="<?php bloginfo( 'stylesheet_url' ); ?>" type="text/css" media="screen" />
<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 a 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.
    • 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().

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 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:
    <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

  • JavaScript code should be placed in external files whenever possible.
  • Use wp_enqueue_script to load your scripts.
  • JavaScript loaded directly into HTML documents (template files) should be CDATA encoded to prevent errors in older browsers.
<script type="text/javascript">
/* <![CDATA[ */
// content of your Javascript goes here
/* ]]> */
</script>

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 it could be saved in PNG, JPEG or GIF format. The recommended image size is 300×225.

Theme Options

Themes can optionally include an options page. For example code, see A Sample WordPress Theme Options Page.

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

  1. 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.
  2. Check template files against Template File Checklist (see above).
  3. Do a run-through using the Theme Unit Test.
  4. Validate HTML and CSS. See Validating a Website.
  5. Check for JavaScript errors.
  6. Test in all your target browsers. For example, IE7, IE8, IE9, Safari, Chrome, Opera, and Firefox.
  7. Clean up any extraneous comments, debug settings, or TODO items.
  8. See Theme Review if you are publicly releasing the Theme by submitting it to the Themes Directory.

Resources and References

Code Standards

Theme Design

CSS

Templates

Testing and QA

Release & Promotion

External Resources & Tutorials