ОНОВЛЕННЯ
З моменту написання цього ядра WordPress додано 'do_parse_request'
гачок, що дозволяє обробляти URL-адреси елегантно та без необхідності розширювати WP
клас. Я детально висвітлював цю тему у своїй розмові про Atlanta WordCamp 2014 року під назвою " Маршрутизація жорстких URL-адрес " ; слайди доступні за посиланням.
ОРИГІНАЛЬНИЙ ВІДПОВІДЬ
Розробка URL-адреси важлива вже більше десяти років; Я навіть писав про це блог кілька років тому. І хоча WordPress сума - це блискуче біт програмного забезпечення, на жаль , система перезапису URL-адрес не вистачає мозкових мертвих (IMHO, звичайно. :). У будь-якому разі, раді бачити людей, які піклуються про дизайн URL-адрес!
Відповідь, яку я буду надати, - це плагін, який я називаю, WP_Extended
що є доказом концепції цієї пропозиції про Trac (зауважте, що пропозиція почалася як одне і перетворилася на іншу, тому вам потрібно прочитати всю річ, щоб побачити, де її очолив.)
В основному ідея полягає в підкласі WP
класу, заміні parse_request()
методу, а потім присвоєнні глобальної $wp
змінної з екземпляром підкласу. Тоді всередині parse_request()
вас фактично оглядають шлях за сегментом шляху, а не використовувати список регулярних виразів, які повинні відповідати URL-адресі в повному обсязі.
Отже, щоб сказати це явно, ця методика вставляє логіку перед parse_request()
якою перевіряє відповідність URL-до-RegEx і замість цього спочатку шукає збіги термінів таксономії, але вона ТІЛЬКИ замінює parse_request()
і залишає цілою рештою системи маршрутизації WordPress URL непошкодженою, включаючи і особливо використання $query_vars
змінної.
У вашому випадку використання це лише порівняння сегментів шляху URL з умовами таксономії, оскільки це все, що вам потрібно. Ця реалізація інспектує таксономії термінів поважаючи батько-дитина тривалі відносини , і коли він знаходить збіг, привласнює URL - шлях (мінус передній і задній косою риси) , щоб $wp->query_vars['category_name']
, $wp->query_vars['tag']
чи $wp->query_vars['taxonomy']
& $wp->query_vars['term']
і обходить parse_request()
метод WP
класу.
З іншого боку, якщо шлях URL не відповідає терміну з вказаної вами таксономії, він делегує логіку маршрутизації URL в систему перезапису WordPress, викликаючи parse_request()
метод WP
класу.
Щоб використовувати WP_Extended
для свого випадку використання, вам потрібно зателефонувати до register_url_route()
функції з functions.php
файлу вашої теми так:
add_action('init','init_forum_url_route');
function init_forum_url_route() {
register_url_route(array('taxonomy'=>'forum'));
}
Що тут вихідного коду для плагіна:
<?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
Хоча для даного сайту я думаю, що ця методика працює чудово, але ця методика НІКОЛИ не повинна використовуватися для плагіна, який розповсюджуватиметься на WordPress.org для інших користувачів . Якщо вона лежить в основі програмного пакету на основі WordPress, то це може бути нормально. В іншому випадку ця методика повинна обмежуватися вдосконаленням маршрутизації URL-адрес для певного сайту .
Чому? Тому що лише один плагін може використовувати цю техніку . Якщо два плагіни спробують використовувати його, вони будуть конфліктувати між собою.
Окрім цього, ця стратегія може бути розширена, щоб загалом обробляти практично кожну модель використання, яка може бути потрібна, і це те, що я маю намір застосувати, як тільки знайду вільний час або клієнта, який зможе спонсорувати час, який знадобиться будувати повністю загальні реалізації.
КАВАТИ №2
Я написав це, щоб переосмислити, parse_request()
що є дуже великою функцією, і цілком можливо, що я пропустив властивість або два глобального $wp
об'єкта, який я мав би встановити .. Тож якщо щось діятиме непросто, дайте мені знати, і я буду радий досліджуйте його і переглядайте відповідь, якщо це буде потрібно.
Все одно ...
'slug' => 'forums'
порожнім, просто видаливши його і просто маючи'rewrite' => array('with_front' => false, 'hierarchical' => true)
? Я думаю, що раніше працювало для мене. Також переконайтеся, що ви змили постійні посилання.