ACTUALIZAR
Desde que escribió este núcleo de WordPress ha agregado el 'do_parse_request'
gancho que permite que el enrutamiento de URL se maneje con elegancia y sin la necesidad de extender la WP
clase. Cubrí el tema en profundidad en mi charla de Atlanta WordCamp 2014 titulada " Enrutamiento de URL Hardcore " ; Las diapositivas están disponibles en el enlace.
RESPUESTA ORIGINAL
El diseño de URL ha sido importante durante más de una década; Incluso escribí un blog al respecto hace varios años. Y aunque WordPress es la suma es un software brillante, desafortunadamente su sistema de reescritura de URL tiene poco cerebro (en mi humilde opinión, por supuesto. :) De todos modos, ¡me alegra ver a las personas preocupadas por el diseño de URL!
La respuesta que voy a proporcionar es un complemento que llamo WP_Extended
que es una prueba de concepto para esta propuesta en Trac (tenga en cuenta que la propuesta comenzó como una cosa y evolucionó hacia otra, por lo que debe leer todo para ver dónde se dirigía)
Básicamente, la idea es subclasificar la WP
clase, anular el parse_request()
método y luego asignar la $wp
variable global con una instancia de la subclase. Luego, dentro de parse_request()
usted, inspeccione la ruta por segmento de ruta en lugar de usar una lista de expresiones regulares que deben coincidir con la URL en su totalidad.
Entonces, para decirlo explícitamente, esta técnica inserta lógica frente a la parse_request()
que verifica las coincidencias de URL a RegEx y, en cambio, primero busca coincidencias de términos de taxonomía, pero SOLO reemplaza parse_request()
y deja intacto todo el resto del sistema de enrutamiento URL de WordPress, incluyendo y especialmente el uso de la $query_vars
variable.
Para su caso de uso, esta implementación solo compara segmentos de ruta URL con términos de taxonomía, ya que eso es todo lo que necesita. Esta implementación inspecciona los términos de la taxonomía que respetan las relaciones entre los términos padre-hijo y cuando encuentra una coincidencia, asigna la ruta URL (menos las barras inclinadas iniciales y finales) a $wp->query_vars['category_name']
, $wp->query_vars['tag']
y $wp->query_vars['taxonomy']
& $wp->query_vars['term']
omite el parse_request()
método de la WP
clase.
Por otro lado, si la ruta de URL no coincide con un término de una taxonomía que haya especificado, delega la lógica de enrutamiento de URL al sistema de reescritura de WordPress llamando al parse_request()
método de la WP
clase.
Para usar WP_Extended
para su caso de uso, deberá llamar a la register_url_route()
función desde el functions.php
archivo de su tema de la siguiente manera:
add_action('init','init_forum_url_route');
function init_forum_url_route() {
register_url_route(array('taxonomy'=>'forum'));
}
Lo que aquí es el código fuente del complemento:
<?php
/*
Filename: wp-extended.php
Plugin Name: WP Extended for Taxonomy URL Routes
Author: Mike Schinkel
*/
function register_url_route($args=array()) {
if (isset($args['taxonomy']))
WP_Extended::register_taxonomy_url($args['taxonomy']);
}
class WP_Extended extends WP {
static $taxonomies = array();
static function on_load() {
add_action('setup_theme',array(__CLASS__,'setup_theme'));
}
static function register_taxonomy_url($taxonomy) {
self::$taxonomies[$taxonomy] = get_taxonomy($taxonomy);
}
static function setup_theme() { // Setup theme is 1st code run after WP is created.
global $wp;
$wp = new WP_Extended(); // Replace the global $wp
}
function parse_request($extra_query_vars = '') {
$path = $_SERVER['REQUEST_URI'];
$domain = str_replace('.','\.',$_SERVER['SERVER_NAME']);
//$root_path = preg_replace("#^https?://{$domain}(/.*)$#",'$1',WP_SITEURL);
$root_path = $_SERVER['HTTP_HOST'];
if (substr($path,0,strlen($root_path))==$root_path)
$path = substr($path,strlen($root_path));
list($path) = explode('?',$path);
$path_segments = explode('/',trim($path,'/'));
$taxonomy_term = array();
$parent_id = 0;
foreach(self::$taxonomies as $taxonomy_slug => $taxonomy) {
$terms = get_terms($taxonomy_slug);
foreach($path_segments as $segment_index => $path_segment) {
foreach($terms as $term_index => $term) {
if ($term->slug==$path_segments[$segment_index]) {
if ($term->parent!=$parent_id) { // Make sure we test parents
$taxonomy_term = array();
} else {
$parent_id = $term->term_id; // Capture parent ID for verification
$taxonomy_term[] = $term->slug; // Collect slug as path segment
unset($terms[$term_index]); // No need to scan it again
}
break;
}
}
}
if (count($taxonomy_term))
break;
}
if (count($taxonomy_term)) {
$path = implode('/',$taxonomy_term);
switch ($taxonomy_slug) {
case 'category':
$this->query_vars['category_name'] = $path;
break;
case 'post_tag':
$this->query_vars['tag'] = $path;
break;
default:
$this->query_vars['taxonomy'] = $taxonomy_slug;
$this->query_vars['term'] = $path;
break;
}
} else {
parent::parse_request($extra_query_vars); // Delegate to WP class
}
}
}
WP_Extended::on_load();
PS CAVEAT # 1
Aunque para un sitio determinado, creo que esta técnica funciona de manera brillante, pero NUNCA debería usarse para que un complemento se distribuya en WordPress.org para que otros lo usen . Si está en el núcleo de un paquete de software basado en WordPress, entonces eso podría estar bien. De lo contrario, esta técnica debería limitarse a mejorar el enrutamiento de URL para un sitio específico .
¿Por qué? Porque solo un complemento puede usar esta técnica . Si dos complementos intentan usarlo, entrarán en conflicto entre sí.
Además, esta estrategia se puede ampliar para manejar genéricamente prácticamente todos los patrones de casos de uso que puedan ser necesarios y eso es lo que pretendo implementar tan pronto como encuentre el tiempo libre o un cliente que pueda patrocinar el tiempo que me tomaría construir implementaciones completamente genéricas.
CUEVA # 2
Escribí esto para anular, parse_request()
que es una función muy grande, y es muy posible que haya omitido una o dos propiedades del $wp
objeto global que debería haber establecido ... Entonces, si algo funciona mal, hágamelo saber y estaré feliz de investigue y revise la respuesta si es necesario.
De todas formas...
'slug' => 'forums'
blanco simplemente eliminándolo por completo y solo teniendo'rewrite' => array('with_front' => false, 'hierarchical' => true)
? Creo que eso ha funcionado en el pasado para mí. También asegúrate de limpiar los enlaces permanentes.