- 1. Creando un tema desde cero para WordPress: Consideraciones previas
- 2. Creando un tema desde cero para WordPress: Escribiendo el tema
- 3. Creando un tema desde cero para WordPress: El loop
- 4. Creando un tema desde cero para WordPress: Acciones al activar/desactivar
Hemos visto en el anterior artículo una serie de consideraciones a tener en cuenta antes de desarrollar un tema para WordPress desde cero. Una vez realizado este planteamiento, es hora de ponerse manos a la obra.
Un tema de WordPress es un conjunto de archivos (.php, .js, .css, etc.) que permiten cambiar la apariencia y funcionalidad de nuestro sitio. Sólo son necesarios dos archivos para que un tema “funcione”: style.css e index.php.
Los temas de WordPress se basan en un sistema de plantillas. Una plantilla es un fichero que representa un tipo de contenido dentro de nuestra web. Hay plantillas para la home, para listados de categorías y etiquetas, para páginas, para el detalle de una entrada, para la pantalla de búsqueda, para cuando nos da un error 404, etc… Los archivos y plantillas que podemos encontrar dentro de un tema de WordPress son las siguientes:
- style.css: hoja de estilos principal, que contiene la información sobre tu tema y puede contener los estilos de tu sitio (veremos más adelante una manera de optimizar esto)
- index.php: plantilla principal del tema, que se mostrará siempre que no se encuentre otra plantilla dentro de la jerarquía de plantillas de WordPress
- home.php: plantilla para listado de post en la página principal
- front-page.php: plantilla para listado de post o página estática
- header.php: plantilla para cargar la cabecera del sitio. Dentro hay que utilizar la función wp_head() antes del cierre de la etiqueta </head>. Esta función es usada por temas y plugins para cargar dinámicamente CSS, JS, etc. También es donde se abre el <body> de nuestro sitio.
- footer.php: plantilla para cargar el pie de nuestro sitio. Dentro hay que utilizar la función wp_footer() antes del cierre de la etiqueta </body>. Esta función es usada por temas y plugins para cargar dinámicamente JS, etc. Es donde se cierra la etiqueta </html> de nuestro sitio.
- page.php: plantilla por defecto para mostrar las páginas.
- category.php: plantilla para mostrar listados de entradas o posts por categoría. Podemos personalizar categorías concretas creando plantillas con la nomenclatura category-{slug}.php ó category-{id}.php
- single.php: plantilla para mostrar el detalle de las entradas o posts. Podemos personalizar el detalle de Custom Post Type concretos creando plantillas con la nomenclatura single-{posttype}.php
- author.php: plantilla para mostrar el autor y sus entradas. Podemos personalizar ésta plantilla para autores concretos creando plantillas con la nomenclatura author-{nicename}.php ó author-{id}.php
- archive.php: plantilla para mostrar listados de entradas de Custom Post Types. Podemos personalizar listados de CPT concretos creando plantillas con la nomenclatura archive-{posttype}.php
- tag.php: plantilla para mostrar listados de entradas o posts por etiqueta. Podemos personalizar etiquetas concretas creando plantillas con la nomenclatura tag-{slug}.php ó tag-{id}.php
- taxonomy.php: plantilla para mostrar listados de entradas o posts por taxonomía. Podemos personalizar taxonomías concretas creando plantillas con la nomenclatura taxonomy-{taxonomy-term}.php ó taxonomy-{taxonomy}.php
- date.php: plantilla para mostrar listados de entradas o posts por fecha (año, mes y día)
- search.php: plantilla para mostrar listados de resultados de búsqueda de posts, pages y CPT.
- searchform.php: plantilla para mostrar el formulario de búsqueda
- 404.php: plantilla de página no encontrada
- comments.php: plantilla de formulario de comentarios
- sidebar.php: plantilla de barra lateral
- functions.php: archivo donde crear las funcionalidades, configuraciones y ajustes del tema.
- screenshot.png: pantallazo o portada de tu tema que aparecerá en el listado de temas en el back-end de WordPress (Apariencia => Temas)
Esto es, a grosso modo, los archivos que conforman un tema de WordPress. Vamos a entrar un poco más en detalle en los archivos más importantes.
style.css
Éste archivo debe contener las cabeceras de información de nuestro tema. Obligatorio al menos el Theme Name:
/*
Theme Name: Nombre de tu tema
Theme URI: URL donde haya información de tu tema
Author: Nombre del autor del tema
Author URI: URL del autor del tema
Description: Breve descripción
Version: Número de versión (p.e. 1.0)
License: Licencia (p.e. GNU General Public License v2 or later)
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: etiquetas
Text Domain: Identificador para hacer tu tema traducible
*/
Normalmente en este archivo escribirás tus estilos CSS, pero si por ejemplo utilizas gulp o grunt para procesar, concatenar y minificar tus CSS no sería necesario. Es decir, el archivo style.css debe existir y debe tener las cabeceras, pero no hace falta que contenga estilos y no es necesario cargarlo en la web, lo veremos más adelante.
header.php
Este archivo contiene las cabeceras de nuestro sitio web, es decir, es donde se define el doctype, el charset, el viewport, se cargan los CSS y JS, etc…y también es donde se abre la etiqueta <body>. Éste archivo suele cargarse en todas las plantillas a través de la función get_header(), por lo tanto es aquí donde pondremos los elementos comunes de nuestro sitio web como puede ser la cabecera, el logo, el menú, etc…
<!DOCTYPE html>
<html <?php language_attributes();?>>
<head>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,600' rel='stylesheet' type='text/css'>
<meta charset="<?php bloginfo( 'charset' );?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="profile" href="http://gmpg.org/xfn/11">
<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
<?php wp_head();?>
</head>
<body <?php body_class();?>>
<?php wp_body_open(); ?>
Aquí va el contenido de la cabecera de página
Como puede observarse, antes del cierre de la etiqueta </head> llamamos a la función wp_head(). Más adelante veremos cómo cargar aquí dinámicamente nuestros archivos CSS y JS desde el functions.php.
Y nada más abrir el body llamamos a la función wp_body_open(), hook que podremos utilizar para lo que queramos pintar en ese punto.
footer.php
Este archivo contiene el pie de página. En él se cierran las etiqueta </body> y </html> abiertas en el header.php:
Aquí va el contenido del pie de página
<?php wp_footer();?>
</body>
</html>
Disponemos de una función wp_footer() para cargar por ejemplo scripts a través del functions.php.
functions.php
Éste es un archivo muy importante en cualquier desarrollo de temas a medida. Contiene todas las configuraciones de nuestro tema. Podremos crear funciones propias para adaptar el tema a nuestras necesidades, crear funciones auxiliares, modificar el funcionamiento de algunas funciones de WordPress, cargar las hojas de estilos y los JS, etc…
Podría extenderme por los siglos de los siglos sobre las cosas que podemos hacer con nuestro functions.php, pero al menos es recomendable tener:
Una función de setup, donde indicar el texdomain en caso de que nuestro tema sea multi-idioma, si soporta thumbnails, title-tag, custom-logo, registrar las áreas de menú, etc…
<?php
function my_theme_setup() {
// Ready for i18n
load_theme_textdomain( "my_theme", TEMPLATEPATH . "/languages");
// Use thumbnails
add_theme_support( 'post-thumbnails' );
// Add default posts and comments RSS feed links to head.
add_theme_support( 'automatic-feed-links' );
// Let WordPress manage the document title
add_theme_support( 'title-tag' );
// Enable support for custom logo.
add_theme_support( 'custom-logo', array(
'height' => 240,
'width' => 240,
'flex-height' => true,
) );
// Register Navigation Menus
register_nav_menus(array(
'header-menu' => 'Header Menu',
'footer-menu' => 'Footer Menu',
));
// Switch default core markup for search form, comment form, and comments to output valid HTML5.
add_theme_support( 'html5', array( 'search-form', 'comment-form', 'comment-list', 'gallery', 'caption' ) );
}
add_action( 'after_setup_theme', 'my_theme_setup' );
Una función para encolar los CSS y JS. Como hemos comentado anteriormente, si usas grunt o gulp para procesar, concatenar y minificar CSS y JS, lo más probable es que tengas en la carpeta /css un archivo llamado styles.min.css y en la carpeta /js un archivo llamado scripts.min.js, por lo tanto:
<?php
function my_theme_cssjs() {
wp_enqueue_style( 'my-theme-style', get_template_directory_uri() . '/css/styles.min.css' );
wp_enqueue_script( 'my-theme-js', get_template_directory_uri() . '/js/scripts.min.js', array( 'jquery' ), '', true );
}
add_action( 'wp_enqueue_scripts', 'my_theme_cssjs' );
Una función para eliminar algunos links de la cabecera:
<?php
// Removes some links from the header
function my_theme_remove_headlinks() {
remove_action( 'wp_head', 'wp_generator' );
remove_action( 'wp_head', 'rsd_link' );
remove_action( 'wp_head', 'wlwmanifest_link' );
remove_action( 'wp_head', 'start_post_rel_link' );
remove_action( 'wp_head', 'index_rel_link' );
remove_action( 'wp_head', 'wp_shortlink_wp_head' );
remove_action( 'wp_head', 'adjacent_posts_rel_link' );
remove_action( 'wp_head', 'parent_post_rel_link' );
remove_action( 'wp_head', 'feed_links_extra', 3 );
remove_action( 'wp_head', 'feed_links', 2 );
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
}
add_action( 'init', 'my_theme_remove_headlinks' );
Una función para establecer el número de palabras que devolverá el extracto:
<?php
function my_theme_excerpt($length) {
return 25;
}
add_filter( 'excerpt_length', 'my_theme_excerpt' );
Y así ir creando el tema en base a tus necesidades…
index.php
Suele usarse para la página principal de tu sitio:
<?php defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
get_header();?>
<!-- contenido -->
<?php get_footer();?>
Ésta estructura nos serviría casi para todas las plantillas, es decir, siempre al principio llamaremos al header, y al final al footer. En medio es donde personalizaremos cada template a nuestro gusto.
A continuación muestro cómo sería por ejemplo un page.php estándar en el que contemplamos el uso de bootstrap con el contenido principal a 9 columnas y el sidebar a 3.
Para mostrar el contenido usamos el loop, del que hablaré con más detalle en la parte 3 de esta serie de artículos sobre cómo hacer un tema de WordPress desde cero:
<?php
/**
* Plantilla para todas las páginas
*/
// Exit if accessed directly
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
get_header();?>
<main class="main-content">
<?php if (have_posts()) :
while (have_posts()) : the_post();?>
<div class="container">
<div class="row">
<div class="col-md-9">
<article id="post-<?php the_ID();?>" <?php post_class();?>>
<h1><?php the_title();?></h1>
<div class="entry-content">
<?php the_content();?>
</div><!-- entry-content -->
</article>
</div>
<div class="col-md-3">
<aside class="sidebar">
<?php get_sidebar();?>
</aside>
</div>
</div><!-- row -->
</div><!-- container -->
<?php endwhile;
endif;?>
</main>
<?php get_footer();
Crea tus propias plantillas
WordPress te permite crear tus propias plantillas para que puedas asignarlas a cada página a tu antojo. Imagina que quieres una plantilla específica para tu página “Donde estamos” ó “Formulario de contacto”.
Solo tendrías que duplicar el archivo page.php de tu tema y nombrarlo como quieras. Yo suelo llamarlos por ejemplo: page-contact.php, page-fullwidth.php, etc…
Para que WordPress lo reconozca como plantilla sólo tienes que poner al inicio:
<?php
/**
* Template Name: Nombre de mi plantilla
*/
El nombre que establezcas aquí aparecerá en el back-end a la hora de editar una página. Siguiendo el ejemplo anterior que he puesto para page.php, imagina que quisieras tener una plantilla de ancho completo, sin sidebar. Puedes crear el archivo page-fullwidth.php con la siguiente estructura:
<?php
/**
* Template Name: Full Width
*/
// Exit if accessed directly
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
get_header();?>
<main class="main-content">
<?php if (have_posts()) :
while (have_posts()) : the_post();?>
<div class="container">
<div class="row">
<div class="col-sm-12">
<article id="post-<?php the_ID();?>" <?php post_class();?>>
<h1><?php the_title();?></h1>
<div class="entry-content">
<?php the_content();?>
</div><!-- entry-content -->
</article>
</div>
</div><!-- row -->
</div><!-- container -->
<?php endwhile;
endif;?>
</main>
<?php get_footer();
Cómo interpreta WordPress qué plantilla mostrar en cada caso
WordPress tiene lo que se llama una jerarquía de plantillas. Cuando un visitante entra en nuestro sitio, a través de unas reglas en nuestro .htaccess si hemos puesto una estructura de enlaces permanentes amigable o a través de parámetros en la URL, detecta el tipo de contenido que quieres ver y te muestra la plantilla correspondiente.
Puedes ver la estructura en la siguiente infografía:
Se llama jerarquía de plantillas porque si no encuentra una en concreto va a la siguiente, y todas desembocan al final en index.php. Por ejemplo, si queremos visualizar el detalle de un custom post type, primero buscará si existe en nuestro tema un archivo single-{posttype}.php.
En caso de no encontrarlo buscará el single.php, y en caso de no encontrarlo, mostrará el index.php.
Es importante entender ésto para tener claro cómo funciona WordPress y permitirnos saber cómo podemos personalizar cada plantilla a nuestro antojo.