Hooks de WordPress explicados de manera sencilla

Voy a intentar explicar los Action Hooks de WordPress de la manera más sencilla posible. A los programadores principiantes les resulta un poco complicado entender este concepto. Es normal si no se ha trabajado nunca en un software que tenga este tipo de arquitectura. Se presuponen conocimientos básicos de programación en PHP. No es necesario conocer nada de la arquitectura de WordPress.

Para ello voy a partir de un supuesto. Una aplicación sencilla que no tiene relación con WordPress. En ella disponemos de dos plantillas para personalizar la cabecera (header.php) y el pie (footer.php).

header.php

<?php
/* header.php */

?>
<html>
<head>
    <title>Nuestro titulo</title>
</head>
<body>
<?

footer.php

<?php
/* footer.php */
?>
</body>
</html>
<?php

Como queremos personalizar el estilo de nuestra página decidimos editar directamente el header.php para enlazar una hoja de estilos. La incrustamos justo antes del tag title.

    <link rel="stylesheet" href="estilos.css" />
    <title>Nuestro titulo</title>

Esta solución funciona pero editar directamente un archivo de la aplicación tiene un problema. Cuando el equipo que desarrolla la aplicación nos entregue una nueva versión del header.php habremos perdido nuestros cambios. Y tendremos que editarlo de nuevo.

¿Cómo se podría evitar esto?

Podríamos pedirle al equipo que mantiene header.php que lo modifique de esta manera:

<?php
/* header.php */

?>
<html>
<head>
    <?php
        if (file_exists('custom_head.php')):
            include 'custom_head.php';
        endif
    ?>
    <title>Nuestro titulo</title>
</head>
<body>
<?

En el fichero custom_head.php es donde vamos ahora a realizar las modificaciones deseadas:

<?php
/* custom_head.php */

?> <link rel="stylesheet" href="estilos.css" /> <?php

De esta forma tan sencilla el problema queda resuelto. Acabamos de diseñar un mecanismo por el que es posible incluir código personalizado en un punto concreto de la aplicación.

La aplicación no sabe nada de nuestro código. De hecho si el fichero custom_head.php no existe ni siquiera se incluirá nada. Este concepto es en el que se basan los Action Hooks de WordPress.

Poniendo un nombre a nuestros Action Hooks

En nuestro ejemplo anterior hemos decidido llamar custom_head.php al fichero que puede emplearse (opcionalmente) para incluir código antes del tag <title>.

¿Pero que ocurre si quisieramos incluir también contenido después de dicho tag? Efectivamente. Podemos añadir otro bloque if y un nuevo fichero.

Ahora tenemos dos puntos diferentes en los que podemos incrustar código. Para evitar confusiones vamos a cambiar el nombre de custom_head.php por before_title.php. El nuevo fichero se llamará after_title.php.

Con esto podemos afirmar que hemos creado nuestros propios Action Hooks:

  • before_title.php: para añadir código antes del título
  • after_title.php: para insertar el código después del título

El nombre de los Action Hooks es muy importante. Con él indicamos la posición exacta en la que deseamos ejecutar nuestro código.

En nuestro ejemplo el equipo que desarrolla la aplicación debería escribir documentación en la que se nos indica el nombre los ficheros que podemos utilizar para añadir nuestro propio código.

Mejorando el diseño de nuestros ganchos

Este sistema funciona pero tiene algunos inconvenientes:

  • Es poco eficiente: el acceso continuo al sistema de ficheros incluso para la más pequeña de las acciones puede suponer una penalización importante en el tiempo de carga del sistema.
  • Tiene sus limitaciones: dos personas que quieran incorporar código en el mismo punto tienen que ponerse de acuerdo ya que tendrán que editar el mismo archivo. No existe una manera de regular la prioridad.

Afortunadamente podemos solucionar esto de manera muy sencilla. Vamos a abandonar la verificación de la existencia de ficheros con ciertos nombres para la inserción del código.

En vez de eso vamos a guardar esta información en la memoria. En una variable global que indique la lista de tareas a ejecutar para cada posición (nombre del hook) y la prioridad que tiene cada una de ellas.

Ya lo tenemos. Así es como funcionan los Action Hooks de WordPress. Vamos a ver los detalles concretos.

La función do_action de WordPress define el punto de ejecucción del action hook

Esta es la definición de la función do_action de WordPress

function do_action( string $tag,  $arg = '' ) {

Donde:

  • $tag: es una cadena de caracteres que indica el nombre del Action Hook
  • $arg: es opcional. Son argumentos adicionales que se pasan a nuestro Action Hook

La documentación de WordPress dice lo siguiente:

Esta función invoca todas las funciones adjuntas al gancho de acción $tag. Es posible crear nuevos ganchos de acción simplemente llamando a esta función, especificando el nombre del nuevo gancho a através del parámetro $tag. Se pueden pasar argumentos a los ganchos de acción.

Utilizando do_action en nuestra aplicación de ejemplo

Para terminar de entenderlo vamos a "migrar" nuestra aplicación de ejemplo al modelo de WordPress. Vamos a crear los ganchos que teníamos en el fichero header.php:

<?php
/* header.php */

?>
<html>
<head>
    <?php do_action('before_title'); ?>
    <title>Nuestro titulo</title>
    <?php do_action('after_title'); ?>
</head>
<body>
<?

Así de simple. Ya hemos definido dos ganchos de acción. Llegado a este punto WordPress echará un vistazo a la tabla de Hooks. Y si encuentra en ella alguno que se llame before_title o after_title lo ejecutará.

Ahora sólo nos falta ver como añadimos los hooks a la tabla. Es lo que vamos a ver a continuación. Para ello vamos a utilizar add_action: la función que WordPress nos proporciona para adjuntar funciones a los ganchos de acción.

La función add_action nos permite conectar funciones con los ganchos de acción

La función add_action es el complemento de do_action.

  • Con do_action creamos puntos de acción.
  • Con add_action definimos qué funciones deben ejecutarse en dichos puntos.

Su definición es la siguiente:

function add_action( string $tag, callable $function_to_add, int $priority = 10, int $accepted_args = 1 ) {

Donde:

  • $tag (requerido): el nombre del Action Hook
  • $function_to_add (requerido): callable de la función a la que se debe llamar
  • $priority (opcional): se usa cuando existen varias funciones definidas para el mismo action hook. Con este parámetro podemos indicar en qué orden deben ejecutarse.
  • $accepted_args (opcional): número de parámetros que la función acepta

Finalizando nuestro ejemplo con add_action

Vamos a terminar la adaptación de nuestra aplicación de ejemplo al modelo de ganchos de WordPress. Ya tenemos el header.php migrado. En nuestros ganchos caseros el código a ejecutar en cada punto lo insertabamos dentro de ficheros externos que definíamos en el punto de inserción del gancho. En este caso ya no existen dichos ficheros.

En vez de eso podemos llamar a add_action desde cualquier otro fichero. La única condición es que se ejecute antes el código add_action que el do_action. En WordPress se suele insertar en el fichero functions.php de nuestro tema. En nuestro ejemplo deberíamos añadirlo en un punto que se ejecute antes de header.php:

<?php
add_action('before_title', 'gancho_antes_titulo');
add_action('after_title', 'gancho_despues_titulo');

function gancho_antes_titulo() {
?><link rel="stylesheet" href="estilos1.css" /><?php
}

function gancho_despues_titulo() {
?><link rel="stylesheet" href="estilos2.css" /><?php
}

Como vemos tenemos que definir dos funciones. Una para cada gancho de acción. Conectamos la función con el gancho mediante llamadas a add_action.

Habíamos dicho que una ventaja de este sistema era la gestión de prioridades. Aquí tenéis un ejemplo:

<?php
add_action('before_title', 'gancho_antes_titulo', 10);
add_action('before_title', 'gancho_antes_titulo_ejecutar_antes', 5);

function gancho_antes_titulo() {
?><link rel="stylesheet" href="estilos.css" /><?php
}

function gancho_antes_titulo_ejecutar_antes() {
?><link rel="stylesheet" href="estilos-prioritarios.css" /><?php
}

Hay dos funciones definidas para el mismo gancho. El tercer parámetro de add_action nos permite indicar la prioridad de ejecucción. Por defecto el valor es 10. Las funciones definidas con valores inferiores se ejecutan primero.

Conclusión

WordPress es un software que cuenta con una arquitectura bien diseñada que utiliza el Hooking como mecanismo para extender, limitar o personalizar el comportamiento de la aplicación.

Los Action Hooks nos permiten adecuar el sistema a nuestras necesidades evitando tocar los ficheros "core" del sistema. Esto evita la pérdida de nuestro trabajo cuando se actualiza el núcleo de WordPress así como algunos ficheros concretos de temas o plugins

Para definir un nuevo gancho de acción se emplea la funcion do_action y para conectar funciones con dicho punto se utiliza add_action. Aunque no lo hemos mencionado también existe la funcion remove_action que permite la eliminación de funciones "enganchadas" a los ganchos de acción.

El principio de funcionamiento de un action hook se basa en la creación de puntos de control en los cuales se indica al sistema la opción de ejecutar instrucciones concretas situadas en cualquier otro lugar. El dominio de estos mecanismos nos permite escribir plugins y temas estructuralmente correctos y nos ayuda a depurar problemas.

Soporte de WooCommerce: el reporte de estado

Cuando necesitamos poner un ticket para obtener soporte técnico en WooCommerce uno de los requisitos es consultar reporte de estado del sistema e intentar solucionar el problema a través de unas pequeñas comprobaciones que WooCommerce nos indica.

Si el problema no se resuelve entonces podemos abrir un ticket de soporte. La información del reporte de estado del sistema debe pegarse en dicho ticket. Este reporte contiene información básica necesaria para los técnicos. Gracias a esta información se intentará reproducir el problema sobre un entorno idéntico al nuestro. Asi la investigación sobre la incidencia y la localización de un posible bug resulta más eficiente.

Reporte de estado del sistema de WooCommerce

Por otra parte, comprender la información de la pantalla "system status" nos puede resultar de mucha utilidad para solucionar algunos problemas.

Entorno de WordPress

En esta tabla encontraremos la información general sobre nuestro sistema WordPress.

Versiones instaladas

En primer lugar los campos WP Version y WC Version nos indican la versión utilizada de WordPress y WooCommerce respectivamente. Esto resulta imprescindible para poder reproducir el entorno e investigar el problema.

URL

Home URL y Site URL indican la dirección principal de nuestro sitio y la ubicación de WordPress. Generalmente es la misma pero algunas personas prefieren instalar WordPress en un subdirectorio propio. En ese caso Home URL es la dirección principal de nuestro sitio y Site URL la del directorio de WordPress.

Otras opciones del entorno de WordPress

Otras opciones aquí mostradas son el directorio en el que se escriben los logs del sistema (y si es escribible o no). Si tenemos la opción MultiSite de WordPress activa. El límite de memoria que puede utilizar WP. Si está activado el sistema Cron de WordPress y el modo de depuración (debug). Y finalmente el idioma utilizado.

Entorno del servidor

Información general sobre el servidor en el que está alojada nuestra aplicación de WordPress / WooCommerce. Esto permite descartar que el problema se deba a otras cuestiones no relacionadas con WordPress o WooCommerce. Las más importantes son:

  • El software HTTP utilizado y su versión: generalmente Apache o Ngnix
  • La versión del intérprete de PHP
  • El sistema de base de datos y su versión: MySQL o MariaDB
  • Algunos valores de configuración del php.ini por ejemplo post_max_size

Base de datos

Aquí vamos a encontrar la versión del esquema de la base de datos. Debería ser la misma que la versión de WooCommerce. Otras opciones listadas son el prefijo utilizado para las tablas y un listado de las mismas con el espacio que ocupan.

Contadores de los tipos de posts en nuestro sistema

Una pequeña tabla con el número de publicaciones que tenemos de cada tipo.

Seguridad

Este apartado solo tiene dos opciones. Primero si estamos utilizando una conexión encriptada (HTTPS) o no. Y segundo si los errores del sistema se muestran a los usuarios (no se deben mostrar errores en el entorno de producción).

Plugins activos

Una lista de cada uno de los plugin que se encontraban activos en el momento de la incidencia junto con la versión instalada de los mismos. Permite detectar con mayor rapidez los errores ocasionados a incompatibilidades entre plugins. En el caso de que existan actualizaciones de los mismos se nos indicará la versión instalda y la versión disponible.

Esta es una de las áreas más importantes del reporte de estado del sistema de WooCommerce. WordPress por su naturaleza es un sistema en el que es habitual instalar numerosos plugins. No es extraño que surjan incompatibilidades entre unos y otros especialmente cuando hay cambio de versiones. Conocer qué plugins se estaban utilizando así como su versión exacta permite aislar el problema de forma más eficiente. Otro apartado muy importante es el de Plantillas invalidadas.

Configuración de WooCommerce

Todos los valores que encontramos en esta sección se refieren a la configuración del propio WooCommerce y no a la de WordPress o la del servidor. Por ejemplo se incluye aquí el tipo de API empleada, la moneda, la configuración regional (separador de miles, numero de decimales, etc. Finalmente se incluyen dos opciones más referentes a las taxonomías: el tipo de productos y la visibilidad de los mismos.

Páginas de WooCommerce

WooCommerce al igual que otros plugins de WordPress necesitan algunas páginas especiales para su correcto funcionamiento. Son páginas normales de WordPress que WooCommerce utiliza para mostrar secciones concretas de la tienda. En esta tabla se indican las páginas elegidas para este propósito:

  • Shop Base: página principal de la tienda
  • Cart: página del carrito de compra
  • Checkout: utilizada para la confirmación del pedido
  • My Account: cuenta del comprador
  • Terms and conditions: condiciones de venta y términos de compra

Tema de WooCommerce

Información sobre el tema activo. En caso de que sea un tema hijo se incluirá también el nombre del tema padre. Se incluye la versión de ambos y si el tema declara o no la compatibilidad con WooCommerce.

Plantillas (invalidadas)

Aquí se muestran todos los ficheros que anulan las plantillas por defecto de WooCommerce. También se indican si han quedado obsoletas. WooCommerce recomienda (en caso de problemas) activar el tema Storefront para asegurarnos de que se están utilizando las plantillas originales.

Conclusión

El reporte de estado del sistema de WooCommerce reune en un único lugar toda la información necesaria para la depuración de problemas y bugs. Tanto si necesitamos soporte técnico como si estamos desarrollando un tema o un plugin y nos encontramos con problemas esta herramienta resulta de gran utilidad.