AGGIORNARE
Da quando ho scritto questo core di WordPress ha aggiunto l' 'do_parse_request'
hook che consente di gestire il routing URL in modo elegante e senza la necessità di estendere la WP
classe. Ho approfondito l'argomento nel mio discorso WordCamp di Atlanta del 2014 intitolato " Hardcore URL Routing " ; le diapositive sono disponibili al link.
RISPOSTA ORIGINALE
La progettazione di URL è stata importante per oltre un decennio; Ne ho persino scritto un blog diversi anni fa. E mentre WordPress è la somma è un brillante pezzo di software, sfortunatamente il suo sistema di riscrittura degli URL è a corto di cervello morto (IMHO, ovviamente. :) Comunque, sono contento di vedere le persone preoccupate della progettazione degli URL!
La risposta che fornirò è un plug-in che sto chiamando WP_Extended
che è una prova di concetto per questa proposta su Trac (nota che la proposta è iniziata come una cosa e si è evoluta in un'altra, quindi devi leggere l'intera cosa per vedere dove era diretto.)
Fondamentalmente l'idea è di sottoclassare la WP
classe, sovrascrivere il parse_request()
metodo e quindi assegnare la $wp
variabile globale con un'istanza della sottoclasse. Quindi, in parse_request()
te, controlla effettivamente il percorso per segmento di percorso invece di utilizzare un elenco di espressioni regolari che devono corrispondere all'URL nella sua interezza.
Quindi, per dirlo esplicitamente, questa tecnica inserisce la logica davanti alla parse_request()
quale verifica le corrispondenze da URL a RegEx e cerca innanzitutto le corrispondenze dei termini della tassonomia, ma sostituisce SOLOparse_request()
e lascia intatto l'intero resto del sistema di routing degli URL di WordPress, incluso e in particolare l'uso della $query_vars
variabile.
Nel tuo caso d'uso questa implementazione confronta solo i segmenti del percorso URL con i termini della tassonomia poiché è tutto ciò di cui hai bisogno. Questa implementazione controlla i termini della tassonomia rispettando le relazioni dei termini genitore-figlio e quando trova una corrispondenza assegna il percorso URL (meno le barre iniziali e finali) a $wp->query_vars['category_name']
, $wp->query_vars['tag']
e $wp->query_vars['taxonomy']
& $wp->query_vars['term']
e ignora il parse_request()
metodo della WP
classe.
D'altra parte se il percorso dell'URL non corrisponde a un termine di una tassonomia che hai specificato, delega la logica di routing dell'URL al sistema di riscrittura di WordPress chiamando il parse_request()
metodo della WP
classe.
Per utilizzare WP_Extended
per il tuo caso d'uso dovrai chiamare la register_url_route()
funzione dal functions.php
file del tuo tema in questo modo:
add_action('init','init_forum_url_route');
function init_forum_url_route() {
register_url_route(array('taxonomy'=>'forum'));
}
Qual è il codice sorgente per il plugin:
<?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
Anche se per un determinato sito penso che questa tecnica funzioni alla perfezione, ma questa tecnica non dovrebbe MAI essere utilizzata per un plugin da distribuire su WordPress.org per essere utilizzato da altri . Se è al centro di un pacchetto software basato su WordPress, potrebbe andare bene. Altrimenti questa tecnica dovrebbe essere limitata al miglioramento del routing degli URL per un sito specifico .
Perché? Perché solo un plugin può usare questa tecnica . Se due plugin tentano di usarlo, entreranno in conflitto tra loro.
A parte questo, questa strategia può essere ampliata per gestire praticamente praticamente ogni modello di caso d'uso che potrebbe essere richiesto ed è quello che intendo implementare non appena trovo il tempo libero o un cliente che può sponsorizzare il tempo necessario per costruire implementazioni completamente generiche.
CAVEAT # 2
Ho scritto questo per sovrascrivere parse_request()
che è una funzione molto grande, ed è del tutto possibile che mi sia sfuggita una o due proprietà $wp
dell'oggetto globale che avrei dovuto impostare .. Quindi se qualcosa si comporta in modo strano, fammi sapere e sarò felice di cercare e rivedere la risposta, se necessario.
Comunque...
'slug' => 'forums'
bianco semplicemente rimuovendolo del tutto e avendo'rewrite' => array('with_front' => false, 'hierarchical' => true)
? Penso che abbia funzionato in passato per me. Assicurati anche di lavare i permalink.