Para un Wordpres Theme: hooks, hooks everywhere

Respuesta rápida

Para facilitar el desarrollo y la escalabilidad de un theme es necesario usar hooks y filters, sobre todo hooks (sin nimiedades, petas el theme de hooks). Una buena manera es apoyarse en la Theme Hook Alliance.

Respuesta completa

A la hora de desarrollar un theme de WordPress -a partir de ahora WP- al final nos encontramos con varios templates que tienen casi el mismo código, y eso significa tener que copiar y pegar el mismo código una y otra vez; es más, si lo cambias en un sitio tendrás que estar cambiándolo en todos lados.

Una manera de solucionar esto es, como hemos visto antes, tener un minitemplate que es llamado por el resto de templates. Poniendo un ejemplo real, index.php, page.php, single.php, …, tienen la llamada get_template_part( ‘loop’ ), que hace referencia a loop.php.

De este modo llamamos a un archivo, pero a veces es mucho mejor llamar solo a una función y así tener muchas funciones en un solo archivo. Ese puente que te permite llamar a una función y ejecutarla en una parte específica del template es un hook.

Pero ,¿qué es exactamente un hook?

Hook significa ‘gancho’ o  ‘anzuelo’. Yo me lo imagino como una caña de pescar.

Una caña de pescar se puede dividir en 3 partes: el anzuelo, el hilo y el mango.

En WP el anzuelo lo pondremos en la parte del template que queremos ejecutar la función. Para ello utilizaremos la función do_action().

Por el otro lado, el mango será el que se encargue de declarar que función se va a declarar. Para ello utilizaremos la función add_action().

¿Y el hilo? El hilo es la palabra clave que conectará estas dos funciones.

Antes de mostrar un ejemplo real les mostraré esta imagen, que es un esquema visual de como funciona un hook.

Understanding WordPress Hook

Un ejemplo real

...
<header>
   <?php do_action('tha_header'); ?>
</header>
...
function my_header() {
   echo 'Oropensando =)';
}

add_action('tha_header', 'my_header');

Así de fácil y sencillo, el ‘hilo’ que usamos es una palabra clave inventada por nosotros.

Bueno, no solo nosotros, WP tiene ya declarados varios hooks que podemos reutilizar porque los ‘hilos’ aquí son infinitos, basta con volver a llamar en el add_action() al mismo ‘hilo’.

Como varias funciones pueden llamar al mismo hook existe un parámetro de prioridad y así poder ordenar las funciones.

A su vez, puede ser necesario que en las funciones se utilicen parámetros de entrada. Todo esto está controlado de la siguiente manera.

do_action($tag, $arg);
//multiples argumentos
do_action($tag, $arg_a, $arg_b, $etc);

$tag es nuestro ‘hilo’, es la misma etiqueta que le vas a poner al add_action() para engancharla aquí.

Los $arg son los parámetros de entrada que tendrá nuestra función a enganchar.

add_action( $hook, $function_to_add, $priority, $accepted_args );

$hook es nuestro ‘hilo’, es el $tag del do_action().

$funtion_to_add es la función a la que vas a llamar para ejecutar su código.

$priotity es la prioridad con respecto a otras funciones que también llamen al mismo hook. Por defecto es ’10’ y se colocan secuencialmente. En caso de que quieras llamar a una función antes de otra tendrás que ordenarlos de menor a mayor.

$accepted_args es el número de argumentos que supuestamente has pedido a través del do_action.

Algo bastante positivo es que los hooks pasan a través del core, y ya sabes lo que dicen:

Cuando lo hace el Core, el Core gana.

Y si no lo sabías pues ya lo sabes, el core siempre será más rápido, práctico y seguro que si lo dejas suelto en medio de un template cualquiera.

Así que adelante, a poner hooks por todos los templates.

Pero, ¿porqué debería usar muchos hooks?

La verdad es que puede que a lo mejor uses 2 o 6 hooks y yo te estoy diciendo de poner fleje do_action() por todos lados, y la razón es de peso.

La razón es ‘porsiaca’, es decir, por si acaso necesites ejecutar una función en ese sitio, y no solo tu, si no cualquier desarrollador que quiera reutilizarte o adaptarse a ti.

Imagínate que tienes un theme con los templates repletos de hooks, antes de la cabecera, después de la cabecera, por la parte de arriba de la cabecera, y por la parte de abajo de la cabecera; a su vez, con el menú de navigación, con el contenido, con la barra lateral, con el pie de página, … Es decir, el esqueleto de los templates está lleno de hooks.

Ahora, imagínate con que facilidad puedes añadir código en los lugares deseados, y no solo tu mismo a través de functions.php, sino también a través de themes hijos y plugins.

Ponerlo en todos lados es muy genérico. ¿Dónde exactamente debería poner los hooks?

Para eso ya existe una alianza de desarrolladores de themes de WP que utilizamos «Theme Hook Alliance«.

Theme Hook Alliance -THA- te dice donde colocar los hooks necesarios para tener theme lleno de hooks necesarios.

Para ayudar a la comunidad de desarrolladores de themes es muy recomendable añadir la librería THA, pero hay que admitir que a veces la librería se queda corta de hooks porque es muy genérica.

Por eso yo adapto THA a mi propia librería de hooks personalizada, en la cual siempre acabo teniendo más hooks.

Posibles problemas

Un problema real que te puede surgir es que la función a la que llames ya exista, puede ser porque eres un torpe que repite nombres, porque piensas igual que otro desarrollador de un plugin que estés usando o que un desarrollador de WP.

El caso es evitar repetir nombre y para eso hay dos modos:

1. Usar prefijos y que los nombres sean largos y feos como el demonio.

2. Encapsular las funciones en una clase única creada por ti.

En caso de que se quiera usar una clase molona para encapsular las funciones sería así:

class oropensando {
   public function my_header() {
      echo 'Oropensando =)';
   }
}

add_action('tha_header', array('oropensando', 'my_header'));

¡WP ya tiene muchos hooks colocados!

El propio WP tiene en su arquitectura muchos hooks para poder personalizar mejor los themes.

En el codex de WP esta la lista de los hooks que tiene WP por defecto. No sé hasta que punto está actualizada, pero los principales están. Los enlaces azules te dan información extra. Los enlaces rojos no te dan información, pero eso no significa que ese hook no exista.

Tirando pa mi terreno

El siguiente paso que le voy a hacer a mi theme Alisios v0.3.2 será implementar toda la estructura de hooks, incluyendo la inclusión de THA.

A su vez, todo el código que pueda modular lo quitaré del template y lo colocaré en funciones.

He aquí el resultado, Alisios v0.4.0.