Codex

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

es:Desarrollo de Temas

This article is a ROUGH DRAFT. The author is still working on this document, so please do not edit this without the author's permission. The content within this article may not yet be verified or valid. This information is subject to change.

Este artículo es acerca de desarrollar Temas de WordPress. Si deseas aprender más acerca de como instalar y usar los Temas, revisa Usar temas. Este asunto se distingue de Usar temas porque discute los aspectos técnicos de escribir código para construir tus propios Temas en vez de cómo activar los temas u obtener nuevos temas.

Porqué Temas de WordPress

Los Temas de WordPress son ficheros que trabajan conjuntamente para crear el diseño y funcionalidad de un sitio de WordPress. Cada tema puede ser diferente, ofreciendo muchas opciones para que los dueños de sitios cambien al instante la apariencia de su sitio web.

Puede que desees desarrollar temas de WordPress para tu propio uso,para el proyecto de un cliente o para mandarlas al directorio de temas de Wordpress submit to the WordPress Theme Directory. ¿Porqué sino deberías construir un tema de Wordpress?

Un tema de WordPress también tiene muchos beneficios.

  • Separa los estilos de presentación y ficheros de plantilla template files de los ficheros del sistema tal que el sitio se modernice sin cambios drásticos para la presentación visual del sitio.
  • Permite personalizar la funcionalidad única del sitio a ese tema.
  • Permite cambios rápidos del diseño visual y la disposición de un sitio WordPress.
  • Elimina la necesidad para un propietario de sitio web de tener que aprender CSS, HTML, y PHP para tener un sitio web que luzca genial.

¿Porqué deberías construir tu propio tema de WordPress? Esa es la verdadera pregunta.

Normas de desarrollo de temas

Los temas de WordPress deberían codificarse utilizando las siguientes normas:

Anatomía de un tema

Los temas de WordPress habitan en subdirectorios del directorio de temas de WordPress (por defecto wp-content/themes/) el cuál no puede ser directamente movido can not be directly moved usando el fichero wp-config.php. çel subdirectorio de temas contiene todos los ficheros de hojas de estilo de tema, ficheros de plantilla template files, y ficheros de funciones opcionales (functions.php), ficheros JavaScript e imágenes. Por ejemplo, un tema llamado "test" residiría en el directorio wp-content/themes/test/. Evita usar números para el nombre del tema, ya que previene de que sea mostrado en la lista de temas disponibles.

WordPress incluye un tema por defecto en cada nueva instalación. Examina los ficheros en el tema por defecto concienzudamente para conseguir una mejor idea de como construir tus propios ficheros de tema.

Para una guía visual, mira esta infografía sobre anatomía de temas de WordPress.

Los temas de WordPress típicamente consisten de tres tipos principales de ficheros, además de imágenes y ficheros JavaScript.

  1. La hoja de estilos llamada style.css, que controla la presentación (diseño visual y disposición) de las páginas de sitios web.
  2. Los ficheros de plantillas de WordPress WordPress template files que controlan el modo en que las paginas del sitio generan la información desde tu base de datos de WordPress a ser mostrada en el sitio.
  3. El fichero de funciones opcionales (functions.php) como parte de los ficheros del tema de WordPress.

Veamoslos individualmente.

Temas hijo

El tema mas simple posible es un tema hijo que incluya únicamente un fichero style.css, más alguna imagen. Esto es posible porque es un hijo de otro tema el cual actúa como su progenitor.

Para una guia detallada para temas hijo, mira Temas Hijo en español, o en inglés Child Themes.

Hoja de estilos de tema

Además de información de estilo CSS para tu tema, style.css provee detalles sobre el tema en forma de comentarios. La hoja de estilo debe proveer detalles sobre el tema en forma de comentarios. No se permiten dos temas que tengan los mismos detalles listados en su comentario encabezadosheaders, ya que esto conllevará problemas en el diálogo deseleccion de tema Theme selection dialog. Sí haces tu propio tema copiando uno ya existente, asegúrate de que cambias su información lo primero.

Lo siguiente es un ejemplo de las pocas primeras lineas de la hoja de estilos, llamada el encabezado de hoja de estilo, para el tema "Twenty Thirteen":

/*
Theme Name: Twenty Thirteen
Theme URI: http://wordpress.org/themes/twentythirteen
Author: the WordPress team
Author URI: http://wordpress.org/
Description: The 2013 theme for WordPress takes us back to the blog, featuring a full range of post formats, each displayed beautifully in their own unique way. Design details abound, starting with a vibrant color scheme and matching header images, beautiful typography and icons, and a flexible layout that looks great on any device, big or small.
Version: 1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: black, brown, orange, tan, white, yellow, light, one-column, two-columns, right-sidebar, flexible-width, custom-header, custom-menu, editor-style, featured-images, microformats, post-formats, rtl-language-support, sticky-post, translation-ready
Text Domain: twentythirteen

This theme, like WordPress, is licensed under the GPL.
Use it to make something cool, have fun, and share what you've learned with others.
*/

NB: El nombre usado para el autor se sugiere que sea el mismo que el nombre de usuario de wordpress.org del autor de tema, aunque puede ser el verdadero nombre del autor también. La opción es del autor del tema.

Nota la lista de etiquetas usadas para describir el tema. Estas permiten al usuario encontrar tu tema utilizando el filtro de etiqueta. Aquí tienes la lista completa de etiquetas permitidas.

Las líneas de comentario del encabezado de style.css son requisito para que WordPress sea capaz de identificar el tema y lo muestre en el panel de administration Administration Panel bajo Diseño Design > Temas Themes como una opción de tema disponible junto con otros temas instalados.


Lineas guía de hojas de estilo

  • Sigue las CSS coding standards normas de codificación de CSS cuando crees tu CSS.
  • Usa CSS válido cuando sea posible. Como una excepción, usa prefijos específicos de vendedores para aprovecharte de las características de CSS3.
  • Minimiza los hacks CSS. La excepción obvia es el soporte a navegadores específicos, habitualmente versiones de IE. Si es posible, separa los hacks CSS en secciones separadas o ficheros separados.
  • Todos los elementos HTML posibles deberían ser estilizados por el tema, tanto en el contenido de la pagina/envíos así como en el contenido de comentarios.
    • Tablas, leyendas, imágenes, listas, citas de bloques, etcétera.
  • Se recomienda encarecidamente añadir estilos pro-impresión.
    • Puedes incluir una hoja de estilo de impresión con media="print" o añadirlo dentro un bloque de medios de impresión en tu hoja de estilo principal.

Functions File

Un tema opcionalmente puede usar un archivo de funciones, que reside en el subdirectorio "theme" y es llamado: functions.php. Este archivo actúa, básicamente como un plugin, y si está presente en el tema que estás usando, es cargado automáticamente durante el inicio de WordPress (tanto para páginas de administración como para páginas externas). Usos Sugeridos para este archivo:

El Tema por defecto de WordPress contiene un archivo functions.php que define muchas de estas características, asi que es posible que desees usarlo como modelo. Ya que functions.php básicamente funciona como un complemento, la lista Function_Reference es el mejor lugar para obtener más información sobre lo que puede hacer con este archivo.

Nota para decidir cuándo agregar funciones a functions.php o a un complemento específico:

Te puedes encontrar con que necesites que la misma función esté disponible para más de un tema principal o tema "padre". Si ese es el caso, la función debe crearse en un plugin en lugar de un functions.php para el tema específico. Esto puede incluir etiquetas de plantilla y otras funciones específicas. Las funciones contenidas en los complementos/plugins serán vistas por todos los temas.

Template Files

Templates son archivos fuente `PHP` utilizados para generar las páginas solicitadas por los visitantes, y se envían como `HTML`. Los archivos de plantilla están formados por `HTML`, `PHP`, y WordPress Template Tags.

Miremos las diversas plantillas que se pueden definir como parte de un tema.

WordPress te permite definir plantillas separadas para los diversos aspectos de tu sitio. Sin embargo, no es esencial tener todos estos diferentes archivos de plantilla para que tu sitio funcione completamente. Las plantillas se eligen y se generan en función de la Template Hierarchy, según las plantillas disponibles en un tema en particular.

Como desarrollador de Temas, puedes elegir qué tanta personalización deseas implementar usando plantillas. Por ejemplo, como caso extremo, puedes usar solo un archivo de plantilla, llamado index.php como la plantilla para todas las páginas generadas y mostradas por el sitio. Un uso muy común es tener diferentes archivos de plantilla para generar resultados diferentes, para permitir la máxima personalización.

Template Files List

Aquí esta la lista de archivos "Theme" reconocidos por WordPress. Por supuesto, su Tema puede contener cualquier hoja de estilos, imágenes o archivos. Sólo tenga en cuenta que lo siguiente tiene un significado especial para WordPress -- vea Template Hierarchy para más información.

style.css
La hoja de estilos principal. Esta debe ser incluída con su tema, y debe contener el encabezado de información para su Tema.
rtl.css
La hoja de estilo rtl. Esta se incluirá 'automáticamente' si la dirección del texto del sitio web es de derecha a izquierda. Esto se puede generar utilizando el complemento/pluggin RTLer.
index.php
La plantilla principal. Si su tema proporciona sus propias plantillas, index.php debe estar presente.
comments.php
La plantilla de comentarios.
front-page.php
La plantilla de la página principal.
home.php
La plantilla de la página de inicio, que es la página principal por defecto. Si usa una static front page, esta es la plantilla de la página con las últimas publicaciones.
single.php
La plantilla de publicación individual. Se usa cuando se consulta una sola publicación. Para esta y todas las demás plantillas de consulta, se utiliza index.php si la plantilla de consulta no está presente.
single-{post-type}.php
The single post template used when a single post from a custom post type is queried. For example, single-book.php would be used for displaying single posts from the custom post type named "book". index.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
The category template. Used when a category is queried.
tag.php
The tag template. Used when a tag is queried.
taxonomy.php
The term template. Used when a term in a custom taxonomy is queried.
author.php
The author template. Used when an author is queried.
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 by category.php, author.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.

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.

Basic Templates

At the very minimum, a WordPress Theme consists of two files:

  • style.css
  • index.php

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:

  • comments.php
  • comments-popup.php
  • footer.php
  • header.php
  • sidebar.php

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.

Here is an example of the include usage:

<?php get_sidebar(); ?>

<?php get_footer(); ?>

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.php for 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 Templates documentation.

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

Query-based Template Files

WordPress can load different Templates for different query types. There are two ways to do this: as part of the built-in Template 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 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.

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

Referencing Files From a 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(): see Referencing Files From a Template.

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

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:

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

Untrusted Data

You should escape dynamically generated content in your Theme, especially content that is output to 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 title, alt, and value attributes.

There are few special template tags for common cases where safe output is needed. One such case involves outputing a post title to a title attribute using the_title_attribute() instead of the_title() to avoid a security vulnerability. Here's an example of correct escaping for the title attribute of a post title link when using translatable text:

<a href="<?php the_permalink(); ?>" title="<?php sprintf( __( 'Permanent Link to %s', 'theme-name' ), the_title_attribute( 'echo=0' ) ); ?>"><?php the_title(); ?></a>

Replace deprecated escape calls with the correct calls: wp_specialchars() and htmlspecialchars() with esc_html(), clean_url() with esc_url(), and attribute_escape() with esc_attr(). See Data_Validation for more.

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

  • 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 saved in PNG format. The recommended image size is 600x450. The screenshot will only be shown as 300x225, but the double-sized image allows for high-resolution viewing on HiDPI displays.

Theme Options

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

When enabling the availability of the 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 Adminstrator role access to the Customize Screen (or maybe some custom screens), be aware that since Version 3.0, this capability is not assigned to the Adminstrator 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 Adminstrator to see the "Theme Options" menu. See the additional capabilities of Adminstrator role when using WordPress Multisite.

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

Functions listing

Testing and QA

Release & Promotion

External Resources & Tutorials