Etiquetas de usuario en permalinks de WordPress

febrero 21, 2009 • Publicado en Software y Hardware
Etiquetas:

Uno de los plugins que he desarrollado para esta página permite la división de un documento en capítulos. La etiqueta ‘nextpage’ de WordPress no ofrecía la funcionalidad que buscaba porque tan solo dividía en secciones sin asignar títulos ni crear un índice, así que desarrollé el plugin Indizar para crear los mecanismos que hacían falta.

En un principio había ideado el plugin para que desde la URL consiguiera la información del número del capítulo. Si la página no usaba permalinks la implementación era sencilla, pero cuando trataba de hacerlo con una página configurada para usar permalinks me encontraba con la difícil tarea de hacer que reconociera cualquier regla asignada desde la configuración. Es obvio que WordPress lo hace, pero la documentación que encontraba siempre me llevaba a puntos muertos. En muchos foros describían en su totalidad los mecanismos para anexar reglas a los permalinks, pero a continuación seguía una larga lista de foristas preguntando cómo hacer que WordPress reconociera las nuevas reglas, y algunos afortunados informaban que de un momento a otro todo estaba funcionado, pero no sabían ni cómo ni por qué. En aquel momento no tenía el tiempo suficiente para recorrer el código de WP buscando una respuesta, así que seguí adelante con el proyecto y dejé de lado mis experimentos con permalinks. Lo más gracioso de todo era que siempre había estado a tan solo un click de la solución. Al final explicaré cuál era el problema.

Luego de varias versiones el plugin era tan funcional como lo había planeado, pero infortunadamente para su instalación se requería añadir una línea de código a un archivo del core de WordPress, lo que podía significar un problema para un usuario promedio. Hace poco me encontré precisamente con un usuario promedio buscando un plugin para hacer capítulos en una página de ‘ciencia ficción’, así que encontré aquella motivación que me faltaba para buscar la solución del plugin con permalinks.

Resumiendo el algoritmo de análisis de permalinks, lo que WordPress hace es comparar la URL con una lista de reglas desde las cuales tratar de encontrar qué información se está enviando al sitio, y una vez identificada la regla extrae los datos a partir de la descripción correspondiente.

A continuación les presento el código documentado que anexa las reglas en Indizar para que WP extraiga la etiqueta /chapter/ desde un permalink.

// Filtro que agrega la variable 'chapter' a las variables del entorno
add_filter('query_vars', 'ind_query_var');

// A partir de WordPress 2.8 el siguiente código ya no sirve para detectar el valor
// de la etiqueta. Al final se especifica otro método que, hasta donde he podido
// comprobar, funciona incluso para versiones anteriores.
// Filtro para asignar 'chapter' a una variable global
add_action('pre_get_posts', 'ind_get_chapter');

// Filtro para generar las reglas del permalink
add_filter('generate_rewrite_rules','ind_rewriteRules');

function ind_query_var($vars) {
        // Para agregar la variable de entorno solo hay que añadirla al arreglo de
        // variables de WP. De esta forma WordPress sabrá que deberá consultar por
        // dicha variable en la URL y almacenarla.
        array_push($vars, 'chapter');
        return $vars;
}

// A partir de WordPress 2.8 el siguiente código ya no sirve para detectar el valor
// de la etiqueta. Al final se especifica otro método que, hasta donde he podido
// comprobar, funciona incluso para versiones anteriores.
function ind_get_chapter($vars) {
// Para que la variable pueda ser consultada en forma global se extrae de
// las variables de WP, así no se necesitará leer el arreglo de variables
// cada que se necesite el valor almacenado en 'chapter'.
global $chapter;
$chapter=1;
if($vars->chapter)
$chapter=$vars->chapter;
}

function ind_rewriteRules($rules){
        // Iniciar el entorno de reescritura de reglas
        global $wp_rewrite;

        // Definir el nombre de la variable, el tipo de valor (numérico en este
        // caso) y la forma en que será transformada en una URL real desde el
        // permalink.
        // La regla del tipo de valor emplea expresiones regulares (RegExp).
        $keytag = '%chapter%';
        $wp_rewrite->add_rewrite_tag($keytag, '([0-9]+)', 'chapter=');

        // La regla de capítulos la definimos así:
        // '/%estructura_de_permalink%/chapter/%capítulo%/'
        $keywords_structure = $wp_rewrite->permalink_structure .
        "/chapter/$keytag";

        // Como la estructura de permalink puede o no terminar en '/' es posible
        // que se cree una cadena que contenga la expresión '//' en la regla, y
        // deberá ser eliminada.
        $keywords_structure = str_replace('//', '/', $keywords_structure);

        // Crear el arreglo de reglas con el nuevo token y la nueva estructura
        // de datos.
        $keywords_rewrite =
                $wp_rewrite->generate_rewrite_rules($keywords_structure);

        // Concatenar las antiguas reglas con las nuevas reglas
        $wp_rewrite->rules = $keywords_rewrite + $wp_rewrite->rules;

        // Fin de la función llamada desde el filtro.
        return $wp_rewrite->rules;
}

Para crear los enlaces a estos ‘capítulos’ empleé el siguiente código

// Si no hay estructura de permalink o se está consultando un borrador, crear un
// enlace con las variables en la URL para ser leidos con $_GET
if ( '' == get_option('permalink_structure') || in_array($post->
   post_status, array('draft', 'pending')) ) {
        // Enlace con la variable que hemos definido en ind_query_var
        $link=get_permalink() . '&chapter=' . $chapter_index;
} else {
        // Enlace con la etiqueta 'chapter/#' al final.
        $link=trailingslashit(get_permalink()) . user_trailingslashit(
           "chapter/".$page_index, 'ch');
}

Supongo que debe haber un mecanismo más sencillo en WP para crear enlaces, pero por el momento este es el que estoy empleando, y hasta ahora ha funcionado sin contratiempos.

Para leer los valores de las etiquetas empleé el siguiente código

// Este código se debe aplicar en las secciones donde se requiere conocer la
// variable. Esta modificación la hice para versiones de WP 2.8 o posteriores porque
// la acción pre_get_post al parecer se comporta en forma diferente. Este código
// también sirve para versiones anteriores de WP.
if ($wp_rewrite->using_permalinks()) { // ¿Usa Permalinks?
        $chapter = $wp_query->query_vars['chapter'];
} else { // No usa Permalinks
        $chapter = $_GET['chapter'];
}

Una vez implementado este código en el plugin hay que hacer un paso extra, que es precisamente el problema que más quebraderos de cabeza me dio antes de descubrir su solución a tan solo unos clicks de distancia. Para que el sitio asigne las nuevas reglas hay que volver a crear el permalink, de lo contrario seguirá empleando las reglas que tiene asignadas en cache. Para recrear el arreglo de reglas hay que ir al módulo de Permalinks en la configuración de WordPress y presionar el botón de ‘Guardar Cambios’; eso es todo, no se necesita más. Con esto WordPress hace un repaso por todos los filtros de asignación y creará las nuevas reglas.

El resultado de este proceso lo pueden ver en las páginas donde hay reportes divididos en capítulos, por ejemplo en el informe sobre el viaje a la Laguna Verde en el Parque de los Nevados (Colombia).

El plugin para manejo de capítulos lo pueden encontrar en su respectiva página.

Nota: En un nuevo reporte se explica cómo agregar reglas orientadas a los reportes asignados como páginas. Recomiendo leer primero el presente artículo para entender los conceptos básico antes de pasar al otro.

Dejar un Comentario