Acciones
Uno de los dos tipos de eventos ofrecidos por WordPress se llama Action, o acción. El propósito de las acciones es permitir la ejecución de procesos propios durante la carga de una página. Algunos ejemplos de estos procesos pueden consistir en modificar información de la base de datos, enviar un mail, registrar nuevos tipos de contenido, o imprimir cierta información en el HTML procesado.
La interacción básica entre eventos y procesos es muy similar al ejemplo de la sección anterior. Las acciones se ejecutan por medio de la función do_action()
, mientras que los hooks se registran usando add_action()
.
<?php
add_action( 'mesa_servida', 'sentarse_a_comer' );
function sentarse_a_comer() {
echo 'a comer!';
}
do_action( 'mesa_servida' );
Sin embargo, este uso básico a veces puede resultar un poco limitado. Por ejemplo, es posible que queramos añadir un segundo hook a mesa_servida
, y necesitemos especificar cuál de ellos va a ejecutarse primero. Supongamos que introducimos la función comer()
, y queremos que se ejecute inmediatamente después de sentarse_a_comer()
.
<?php
add_action( 'mesa_servida', 'comer' );
function comer() {
echo 'comiendo ...';
}
add_action( 'mesa_servida', 'sentarse_a_comer' );
function sentarse_a_comer() {
echo 'a comer!';
}
do_action( 'mesa_servida' );
Con este código, la función comer()
siempre se va a ejecutar antes de sentarse_a_comer()
. Si no tenemos la posibilidad de cambiar la ubicación de la asignación de add_action( 'mesa_servida', 'comer' )
, necesitamos encontrar una manera de hacer que comer()
se ejecute después de sentarse_a_comer()
. Para este tipo de necesidades, la función add_action()
admite un tercer parámetro llamado $priority
, en el cual se especifica un valor numérico. Los hooks con valores menores van a ser ejecutados con anterioridad a los hooks con valores más altos, y el valor por defecto es 10. Teniendo esto en cuenta, podemos modificar nuestro código de esta manera.
<?php
add_action( 'mesa_servida', 'comer', 20 );
function comer() {
echo 'comiendo ...';
}
add_action( 'mesa_servida', 'sentarse_a_comer', 10 );
function sentarse_a_comer() {
echo 'a comer!';
}
do_action( 'mesa_servida' );
// Se imprime "a comer!"
// Se imprime "comiendo ..."
Puede pasar, también, que dentro de las funciones que usamos como hooks necesitemos algún tipo de información contextual con respecto al momento en el que se ejecuta la acción. Supongamos que dentro de sentarse_a_comer()
necesitamos evaluar cuántos comensales vamos a tener.
<?php
add_action( 'mesa_servida', 'sentarse_a_comer', 10 );
function sentarse_a_comer( $comensales ) {
if ( $comensales < 5 ) {
echo 'a comer!';
} else {
echo 'acá hay demasiada gente, Roberto!'
}
}
$comensales = 10;
do_action( 'mesa_servida' );
// Se imprime "a comer!"
De alguna manera necesitamos hacer que ese número de comensales declarado en el mismo contexto de ejecución de do_action( 'mesa_servida' )
llegue a la función sentarse_a_comer()
. Para esto podemos adjuntar a do_action()
todos los parámetros que queramos, y en add_action()
especificar, en un cuarto parámetro llamado $accepted_args
, el número de parámetros que va a recibir nuestro hook.
<?php
add_action( 'mesa_servida', 'sentarse_a_comer', 10, 1 );
function sentarse_a_comer( $comensales ) {
if ( $comensales < 5 ) {
echo 'a comer!';
} else {
echo 'acá hay demasiada gente, Roberto!';
}
}
$comensales = 10;
do_action( 'mesa_servida' , $comensales );
// Se imprime "acá hay demasiada gente, Roberto!"
El valor por defecto de $accepted_args
es 1, por lo cual, si vamos a tener un solo parámetro, podemos incluso no especificar este valor.
<?php
add_action( 'mesa_servida', 'sentarse_a_comer', 10 );
function sentarse_a_comer( $comensales ) {
if ( $comensales < 5 ) {
echo 'a comer!';
} else {
echo 'acá hay demasiada gente, Roberto!';
}
}
$comensales = 10;
do_action( 'mesa_servida' , $comensales );
// Se imprime "acá hay demasiada gente, Roberto!"
Sin embargo, podemos pasarle a do_action()
tantos parámetros como necesitemos en nuestra función, pero siempre especificando la cantidad en add_action()
, en caso de que sea más de uno.
<?php
add_action( 'mesa_servida', 'sentarse_a_comer', 10, 2 );
function sentarse_a_comer( $comensales, $comida ) {
if ( $comensales < 5 ) {
echo 'A comer!';
} else {
echo 'Acá hay demasiada gente, Roberto! Tenemos solamente ' . $comida;
}
}
$comensales = 10;
$comida = 'Fideos con pesto';
do_action( 'mesa_servida', $comensales, $comida );
// Se imprime "acá hay demasiada gente, Roberto! Tenemos solamente fideos con pesto"
Sabiendo cómo opera este tipo de evento, también podemos agregar hooks a las acciones nativas de WordPress. Para ejemplificar esto vamos a crear un plugin muy básico, y que tiene un solo propósito: mandarle un mail al administrador del sitio cada vez que se publique un nuevo post. Para esto, definimos la función que envía el mail, y se la asignamos como hook a la acción publish_post
.
<?php
/*
Plugin Name: Aviso de Actualización
*/
add_action( 'publish_posts' ,'avisar_amigos' );
function avisar_amigos() {
$amigos = '[email protected],[email protected]';
mail( $amigos, 'Actualización de blog', 'Acabo de actualizar mi blog: http://blog.example.com' );
}
Una vez que activemos este nuevo plugin y publiquemos un nuevo post, vamos a poder ver que llega un nuevo mail a las casillas de correo especificadas en la función.
Nótese que no estamos llamando directamente a do_action( 'publish_posts' );
. Esto es porque ese llamado se va a estar haciendo en algún lugar del código base de WordPress, que llamamos Core. WordPress cuenta con una lista bastante larga de acciones propias a las que podemos asignar nuestros propios hooks, la cual nos puede servir a manera de guía.
Si queremos, también podemos crear y usar acciones propias. Por ejemplo, si yo quisiera que, una vez que se envió el mail al administrador, también se envíe un mail a una casilla de correo específica, puedo ejecutar una acción una vez que se envía el primer mail, y asignarle como hook una segunda función.
<?php
/*
Plugin Name: Aviso de Actualización
*/
add_action( 'publish_posts' ,'avisar_amigos' );
function avisar_amigos() {
$amigos = '[email protected],[email protected]';
if ( mail( $amigos, 'Actualización de blog', 'Acabo de actualizar mi blog: http://blog.example.com' ) ) {
do_action( 'email_enviado' );
}
}
add_action( 'email_enviado' , 'avisarme' );
function avisarme() {
mail( '[email protected]', 'Se publicó post y se envió mail a amigos' );
}
De esta manera, si el envío del primer mail fue exitoso, se va a ejecutar la acción email_enviado
. Como esta acción tiene asignada la función avisarme()
como hook, va e enviarse un segundo mail a la dirección de correo especificada en dicha función.