ATUALIZAR
Desde a criação deste núcleo do WordPress, foi adicionado um 'do_parse_request'
gancho que permite que o roteamento de URL seja tratado com elegância e sem a necessidade de estender a WP
classe. Eu cobri o tópico em profundidade na minha palestra de 2014 do Atlanta WordCamp intitulada " Hardcore URL Routing " ; os slides estão disponíveis no link.
RESPOSTA ORIGINAL
O design de URL tem sido importante há mais de uma década; Eu até escrevi um blog sobre isso há vários anos. E, embora o WordPress seja um software brilhante, infelizmente , o sistema de reescrita de URLs está quase morto (IMHO, é claro. :) De qualquer forma, fico feliz em ver as pessoas se preocupando com o design do URL!
A resposta que vou fornecer é um plug-in que estou chamando WP_Extended
que é uma prova de conceito para esta proposta no Trac (observe que a proposta começou como uma coisa e evoluiu para outra, então você deve ler a coisa toda para ver onde foi dirigido.)
Basicamente, a idéia é subclassificar a WP
classe, substituir o parse_request()
método e atribuir a $wp
variável global a uma instância da subclasse. Em seguida, parse_request()
você inspeciona o caminho por segmento, em vez de usar uma lista de expressões regulares que devem corresponder ao URL na sua totalidade.
Portanto, para declarar explicitamente, essa técnica insere lógica na frente da parse_request()
qual verifica correspondências de URL para RegEx e, em vez disso, procura primeiro correspondências de termos de taxonomia, mas apenas substitui parse_request()
e deixa intacto o restante do sistema de roteamento de URL do WordPress, incluindo e especialmente o uso da $query_vars
variável
Para seu caso de uso, essa implementação compara apenas os segmentos do caminho da URL com os termos de taxonomia, pois é tudo o que você precisa. Essa implementação inspeciona os termos de taxonomia que respeitam os relacionamentos pai-filho e, quando encontra uma correspondência, atribui o caminho da URL (menos as barras à esquerda e à direita) a $wp->query_vars['category_name']
, $wp->query_vars['tag']
ou $wp->query_vars['taxonomy']
& $wp->query_vars['term']
e ignora o parse_request()
método da WP
classe.
Por outro lado, se o caminho da URL não corresponder a um termo de uma taxonomia especificada, ele delegará a lógica de roteamento de URL ao sistema de reescrita do WordPress chamando o parse_request()
método da WP
classe.
Para usar WP_Extended
no seu caso de uso, você precisará chamar a register_url_route()
função no functions.php
arquivo do seu tema da seguinte maneira:
add_action('init','init_forum_url_route');
function init_forum_url_route() {
register_url_route(array('taxonomy'=>'forum'));
}
Qual é o código fonte do plug-in:
<?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
Embora para um determinado site eu ache que essa técnica funcione de maneira brilhante, mas NUNCA deve ser usada para que um plug-in seja distribuído no WordPress.org para que outros o usem . Se estiver no centro de um pacote de software baseado no WordPress, tudo bem. Caso contrário, essa técnica deve se limitar a melhorar o roteamento de URL para um site específico .
Por quê? Porque apenas um plugin pode usar esta técnica . Se dois plugins tentarem usá-lo, eles entrarão em conflito.
Além disso, essa estratégia pode ser expandida para lidar genericamente com praticamente todos os padrões de casos de uso que possam ser necessários, e é isso que pretendo implementar assim que encontrar o tempo livre ou um cliente que possa patrocinar o tempo que levaria para construir implementações totalmente genéricas.
CAVEAT # 2
Eu escrevi isso para substituir parse_request()
uma função muito grande, e é bem possível que eu tenha perdido uma propriedade ou duas do $wp
objeto global que eu deveria ter definido. Portanto, se algo funcionar errado, avise-me e ficarei feliz em pesquise e revise a resposta, se necessário.
De qualquer forma...
'slug' => 'forums'
branco apenas removê-lo completamente e apenas ter'rewrite' => array('with_front' => false, 'hierarchical' => true)
? Eu acho que isso funcionou no passado para mim. Além disso, certifique-se de liberar os links permanentes.