Los shortcodes, «códigos cortos» en inglés, son una aplicación de WordPress muy útil. Sirven para ejecutar una función mediante una simple cadena de texto puesta entre corchetes:
- [shortcode]
Por ejemplo, para incluir una imagen con el plugin NextGenGallery se escribe un shortcode similar a este en el panel de entrada:
[[singlepic id=12 w=350 h=135 float=center]]
Luego, cuando la entrada se «renderiza» en el front-end, la web que ven los usuarios, para aclararnos, WordPress traduce ese shortcode, es decir, lo reemplaza por el código que permite ampliar las imágenes al pulsarlas, como ocurre con esta pintura de Boticcelli.
[singlepic id=12 w=350 h=135 float=center]
Hay tres tipos de shortcodes:
Sencillos, que solo necesitan ser escritos para ejecutar el código correspondiente:
[mishortocode]
Con valores, en los que se envía uno o más datos (atributos) a la función para que sean procesados, como por ejemplo qué imagen debe ser insertada:
[mishortocode $valor]
De entrada y cierre, en los que se insertan elementos entre una declaración de apertura del shortcode y otra de cierre definida por la barra invertida:
[mishortocode] texto a tratar por el shortcode [/mishortocode]
Bueno, y hasta aquí la parte aburrida, vamos ahora con la divertida :-).
Para ver cómo funciona el tinglado, vamos a hacer un shortcode muy sencillo, pero fundamental en cualquier blog, uno que escriba con formato de cita los siguientes versos de un poema de Pessoa:
Que grande constipação física!
Preciso de verdade e de aspirina.
Todos los shortcodes van en el archivo functions.php, así que lo abrimos con nuestro editor favorito, en mi caso Notepad++, y añadimos esta función que comentaré a continuación:
- function shortcode_poema() {
- $versos = "Que grande constipação física! / Preciso de verdade e de aspirina.";
- $versos = htmlentities ($versos);
- $versos = str_replace ("/","<br />",$versos);
- $versos = "<blockquote>".$versos."</blockquote>";
- return $versos;
- }
- add_shortcode('poemas', 'shortcode_poema');
En la línea 2 definimos en la variable $versos la cadena de texto con los dos versos separados por una barra inclinada.
En la línea 3 pasamos todos los acentos, eñes y demás caracteres rarunos a caracteres html por ejemplo, la í se convierte en í.
En la línea 4 reemplazamos la barra inclinada (/) en el tag de html <br />, que define un salto de línea.
En la línea 5 incluimos antes y después de la cadena de texto el tag de apertura y cierre de las citas (<blockquote></blockquote>), que en mi hoja de estilo tengo definido que se muestren indentadas y con un borde naranja a la izquierda.
En la línea 6 devolvemos la cadena al lugar desde donde fue llamada, en este caso el shortcode, mediante la sentencia return.
En la línea 8 añadimos un hook, un gancho, para que la función se active al cargarse la página:
En el primer parámetro se define el nombre con el que luego se usará el shortcode y en el segundo el nombre de la función, los dos entre comillas simples y separados por comas.
Ahora si escribimos [poemas] en algún lado, como una entrada o en el sidebar (ver bonus) se escribirán de forma automática los versos de Pessoa.
Importante: en el nombre de los shortcodes hay que evitar los guiones (poemas-de-pessoa) y los CamelCase (mayúsculas de camello), que son típicas de JavaScript y consisten en poner en mayúscula la primera letra de cada palabra (PoemasDePesoa). De hecho, conviene que sean siempre en minúscula, incluido el nombre de sus propiedades, que veremos a continuación.
Importante++: en la función no hay que utilizar echos de PHP, pues no se tratarían de forma correcta desde el sitio donde se esté lanzando el shortcode, sino devolver el resultado con un return.
Shortcodes con atributos
Como ocurre con cualquier otra función, podemos pasar valores mediante un shortcode. Es tan sencillo como recuperarlos en la función. Por ejemplo, a la función anterior vamos a añadirle una estructura condicional, si el valor pasado es un 1 mostrará los versos de Pessoa y si es un 2, unos de Kavafis.
- function shortcode_poema($atts) {
- if ($atts['poeta'] == 1) {
- $versos = "Que grande constipação física! / Preciso de verdade e de aspirina.";
- } elseif ($atts['poeta'] == 2) {
- $versos = "Cuando emprendas tu viaje a Itaca / pide que el camino sea largo";
- }
- $versos = htmlentities ($versos);
- $versos = str_replace ("/","<br />",$versos);
- $versos = "<blockquote>".$versos."</blockquote>";
- return $versos;
- }
- add_shortcode('poemas', 'shortcode_poema');
Ahora si escribimos [poemas poeta="1"] se mostrarán los versos de Pessoa, pero con [poemas poeta="2"] los de Kavafis.
Cuando emprendas tu viaje a Itaca
pide que el camino sea largo
La clave de este tipo de shortcodes se encuentra en la variable $atts, que recoge todos los valores especificados en los atributos del shortcode en un array. Es decir, con este shortcode [poemas poeta="1"] es como si hubiéramos invocado esta función:
- function shortcode_poema(array(poeta=>1)) {
- ...
Así, en las líneas 2 y 4 lo único que queda por hacer es decirle que si el valor poeta del array es 1 haga unas cosas y si es 2, otras. Pero esto se puede hacer de forma más clara, sobre todo si hay más de una propiedad, mediante la función shortcode_atts($atts) de WordPress junto con la función extract(array) de PHP.
Con shortcode_atts se distribuyen los valores de las propiedades recogidos en $atts en un array asociativo formado por una clave y valor, que en nuestro caso serían el nombre de la propiedad del shortcode (poeta) y su valor (1 ó 2). Y con extract() se convierte cada par clave/valor de un array en una variable con un valor. Por ejemplo, en el caso anterior, en vez de trabajar directamente con el array recogido en $atts, podríamos haber hecho esto:
- function shortcode_poema($atts) {
- extract(shortcode_atts(array('poeta' => $atts), $atts));
- if ($poeta == 1) {
- $versos = "Que grande constipação física! / Preciso de verdade e de aspirina.";
- } elseif ($poeta == 2) {
- $versos = "Cuando emprendas tu viaje a Itaca / pide que el camino sea largo";
- }
- ...
De esa forma, hemos recuperado la propiedad «poeta» del shortcode en un array que luego hemos convertido en variables. Esto se entiende bien si añadimos una segunda propiedad a la función, en la cual vamos a definir en RGB el color de la fuente con que deben mostrarse los versos.
[poemas poeta="1" color_fuente="900"]
Y en la función recogemos el valor del color mediante shortcode_atts()
- function shortcode_poema($atts) {
- extract(shortcode_atts(array('poeta' => $atts, 'color_fuente'=> $atts), $atts));
- if ($poeta == 1) {
- $versos = "Que grande constipação física! / Preciso de verdade e de aspirina.";
- } elseif ($poeta == 2) {
- $versos = "Cuando emprendas tu viaje a Itaca / pide que el camino sea largo";
- }
- $versos = htmlentities ($versos);
- $versos = str_replace ("/","<br />",$versos);
- $versos = "<blockquote style='color:#".$color_fuente.";'>".$versos."</blockquote>";
- return $versos;
- }
- add_shortcode('poemas', 'shortcode_poema');
Una ventaja de este método es que permite asignar valores por defecto a los atributos del shortcode, pues, al recuperarse en la función, los valores de $atts pisan los que estén definidos. De esa manera, si no se han especificado en el shortcode, coge el que lleva por defecto. Por ejemplo, en nuestro caso vamos a especificar que el color de la fuente sea azul (06c) si no llega ninguno desde el shortcode.
Así, esto [poemas poeta="1" color_fuente=""] pasado por la función
- function shortcode_poema($atts) {
- extract(shortcode_atts(array('poeta' => $atts, 'color_fuente'=> '06c'), $atts));
- ...
da como resultado una fuente azul (06c), pero este otro shortcode [poemas poeta="2" color_fuente="909"], donde sí se ha definido el color mostraría la fuente en morado (909):
Cuando emprendas tu viaje a Itaca
pide que el camino sea largo
Bueno, espero que se entienda hasta aquí. Seguimos. 🙂
Ya solo nos queda por ver cómo encorchetar contenido entre dos shortcodes, por ejemplo, para enviar directamente a la función los versos que debe mostrar como cita. Para eso, añadimos la variable $content a la función y le asignamos un valor por defecto de null (nulo).
- function shortcode_poema($atts, $content = null) {
- extract(shortcode_atts(array('color_fuente'=> '06c'), $atts));
- $versos = str_replace ("/","<br />",$content);
- $versos = "<blockquote style='color:#".$color_fuente.";'>".$versos."</blockquote>";
- return $versos;
- }
- add_shortcode('poemas', 'shortcode_poema');
Ahora [poemas color_fuente="900"] Dios mueve al jugador, y éste, la pieza. /¿Qué Dios detrás de Dios la trama empieza /de polvo y tiempo y sueño y agonía? [/poemas] daría como resultado este poema de Borges
"Dios mueve al jugador, y éste, la pieza.
¿Qué Dios detrás de Dios la trama empieza
de polvo y tiempo y sueño y agonía?
Además, también se pueden incluir shortcodes en shortcodes, lo cual es muy útil en algunos casos, como un menú por tabuladores, y para eso hay que usar la función do_shortcode(), que fuerza la ejecución de un shortcode donde se escriba, incluido dentro de un shortcode.
- <?php echo do_shortcode( 'nombre_del_shortcode_a_ejecutar') ?>
Por ejemplo, vamos añadir un shortcode que ponga en minúscula todas las letras mediante la función strtolower() de PHP.
Con esta función
- function shortcode_minuscula($atts, $content = null) {
- $minuscula = strtolower ($content);
- return $minuscula;
- }
- add_shortcode('minuscula', 'shortcode_minuscula');
este shortcode [minuscula]SOY UN TEXTO QUE SE VERÁ EN MINÚSCULA[/minuscula] sería devuelto así:
«soy un texto que se verá en minuscula»
Sin embargo, si ponemos directamente este shortcode sin retocar la función que teníamos antes:
[poemas]Dios mueve al jugador, y éste, la pieza. / [minuscula]¿QUÉ DIOS DETRÁS DEL DIOS [minuscula] la trama empieza / de polvo y tiempo y sueño y agonía? [/poemas]
No cogerá el shortcode minuscula y el resultado será este (partiendo la frase donde encuentra la barra inclinada de cierre del segundo shortcode, además de no interpretar el de minúscula):
Dios mueve al jugador, y éste, la pieza.
[minuscula]¿QUÉ DIOS DETRÁS DEL DIOS[
minuscula] la trama empieza
de polvo y tiempo y sueño y agonía?
Pero la cosa cambia si añadimos la función do_shortcode en el shortcode mayor (el que encorcheta al otro) forzándole a ejecutar todos los shortcodes que contiene $content.
- function shortcode_poema($atts, $content = null) {
- extract(shortcode_atts(array('color_fuente'=> '06c'), $atts));
- $content = do_shortcode($content);
- $versos = str_replace ("/","<br />",$content);
- $versos = "<blockquote style='color:#".$color_fuente.";'>".$versos."</blockquote>";
- return $versos;
- }
- add_shortcode('poemas', 'shortcode_poema');
Y ahora sí que funcionaría.
No es sensato llenar el archivo functions.php de shortcodes, ya que si luego cambias de tema, si no te acuerdas de copiarlos en el nuevo tema no funcionarán. Una solución para evitar esos posibles despistes es pluginizar los shortcodes, que es un proceso muy sencillo.
1) Se crea un archivo PHP que tenga un nombre que con toda seguridad no vaya a poner alguien igual por casualidad en otro plugin. Por ejemplo, poniendo de prefijo las iniciales del nombre y los apellidos, lo que en mi caso daría mmf y luego ya el nombre del plugin: mmf-poetas.php.
2) En las primeras líneas del archivo se indican los siguientes datos (insisto que otro día lo vemos ya en detalle):
- <?php
- /*
- Plugin Name: el nombre del plugin
- Plugin URI: la url desde donde se puede descargar
- Description: lo que hace
- Version: la versión
- Author: el autor
- Author URI: la url del autor
- License: la licencia
- */ ?>
Para poder escribir shortcodes en otros sitios que no sean los post hay que indicarlo en el archivo functions.php mediante estas sentencias:
En los widgets del sidebar
- add_filter('widget_text', 'do_shortcode');
En los comentarios
- add_filter( 'comment_text', 'do_shortcode' );
En los sumarios (excerpt)
- add_filter( 'the_excerpt', 'do_shortcode');
En categorías y tags
- add_filter( 'term_description', 'do_shortcode' );
Para escapar un shortcode, basta con poner dos corchetes seguidos
[[soy_un_shortcode_escapado]]
Bueno, otro día vemos algunos ejemplos, de momento vamos a dejarlo aquí. 🙂