Я создал таксономию 'форума', с помощью этих правил:
register_taxonomy(
'forum',
array('topic'),
array(
'public' => true,
'name' => _a('Forums'),
'singular_name' => _a('Forum'),
'show_ui' => true,
'show_in_nav_menus' => true,
'hierarchical' => true,
'labels' => array(
'name' => _a('Forums'),
'singular_name' => _a('Forum'),
'search_items' => _a('Search Forums'),
'popular_items' => _a('Popular Forums'),
'all_items' => _a('All Forums'),
'parent_item' => _a('Parent Forum'),
'parent_item_colon' => _a('Parent Forum:'),
'edit_item' => _a('Edit Forum'),
'update_item' => _a('Update Forum'),
'add_new_item' => _a('Add New Forum'),
'new_item_name' => _a('New Forum Name'),
),
'query_var' => true,
'rewrite' => array('slug' => 'forums', 'with_front' => false, 'hierarchical' => true),
)
);
Во фронтенде URL похож:
forums/general-discussion/sub-forum
Как я могу удалить передний краткий заголовок ("форумы")? Т.е., измените URL на:
general-discussion/sub-forum
Если я передаю пустой аргумент краткого заголовка register_taxonomy (), он работает, но это вызывает проблемы с постоянными ссылками типа сообщения, связанного с этой таксономией
Начиная с записи этого ядра WordPress добавил 'do_parse_request'
рычаг, который позволяет маршрутизации URL быть обработанной изящно и без потребности расшириться WP
класс. Я затронул тему, всестороннюю в моем атлантском разговоре WordCamp 2014 года, наделенном правом "Жесткая Маршрутизация URL"; слайды доступны в ссылке.
Дизайн URL был важен, чтобы быть в течение хорошо более чем десятилетия; я даже записал блог об этом несколько лет назад. И в то время как WordPress является суммой, блестящий бит программного обеспечения, к сожалению, это - URL, переписывают систему, только за исключением глупого (по моему скромному мнению, конечно.:) Так или иначе, довольный видеть, что люди заботятся о дизайне URL!
Ответ, который я собираюсь предоставить, является плагином, который я называю WP_Extended
это - подтверждение концепции этого предложения по Trac (Обратите внимание, что предложение запустилось как одна вещь и развитый из другого, таким образом, необходимо считать всю вещь видеть, куда это направилось.)
В основном идея состоит в том, чтобы разделить на подклассы WP
класс, переопределите parse_request()
метод, и затем присваивает глобальное $wp
переменная с экземпляром подкласса. Затем в parse_request()
Вы на самом деле осматриваете путь сегментом контура вместо того, чтобы использовать список регулярных выражений, которые должны соответствовать URL в их полноте.
Таким образом для утверждения этого явно эта техника вставляет логику перед parse_request()
который проверяет на соответствия URL-to-RegEx и вместо этого сначала ищет соответствия термина таксономии, но это ТОЛЬКО заменяет parse_request()
и оставляет весь отдых системы маршрутизации URL WordPress неповрежденным включая и особенно использование $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();
Хотя для данного сайта я думаю, что эта техника работает блестяще, но эта техника никогда не должна использоваться, чтобы плагин был распределен на WordPress.org для других для использования. Если это в ядре пакета программного обеспечения на основе WordPress затем, это могло бы быть хорошо. Иначе эта техника должна быть ограничена улучшением маршрутизации URL для определенного сайта.
Почему? Поскольку только один плагин может использовать эту технику. Если два плагина попытаются использовать его, то они будут конфликтовать друг с другом.
Поскольку в стороне эта стратегия может быть расширена, чтобы в общем обработать практически каждый шаблон примера использования, который мог требоваться, и это - то, что я намереваюсь реализовать, как только я или нахожу свободное время или клиент, который может спонсировать время, когда это взяло бы для создания полностью универсальных реализаций.
Я записал это для переопределения parse_request()
который является очень большой функцией, и довольно возможно, что я пропустил свойство или два из глобальных $wp
возразите, что я должен был установить.. Таким образом, если что-то действует сообщенный мне wonky, и я буду рад исследовать его и пересмотреть ответ в случае необходимости.
Так или иначе...
Простой, действительно.
Шаг 1: Прекратите использовать переписать параметр вообще. Мы идем в самокрутку, переписывает.
'rewrite'=>false;
Шаг 2: Установите подробные правила страницы. Это вынуждает нормальные Страницы иметь свои собственные правила вместо того, чтобы быть вместилищем внизу страницы.
Шаг 3: Создайте некоторые переписывают правила обработать Ваши варианты использования.
Шаг 4: Вручную вызовите сброс правила произойти. Самый легкий путь: перейдите к настройкам-> постоянная ссылка и нажмите кнопку сохранения. Я предпочитаю это по сменному методу активации для моего собственного использования, так как я могу вызвать правила сбросить каждый раз, когда я меняю вещи.
Так, время кода:
function test_init() {
// create a new taxonomy
register_taxonomy(
'forum',
'post',
array(
'query_var' => true,
'public'=>true,
'label'=>'Forum',
'rewrite' => false,
)
);
// force verbose rules.. this makes every Page have its own rule instead of being a
// catch-all, which we're going to use for the forum taxo instead
global $wp_rewrite;
$wp_rewrite->use_verbose_page_rules = true;
// two rules to handle feeds
add_rewrite_rule('(.+)/feed/(feed|rdf|rss|rss2|atom)/?$','index.php?forum=$matches[1]&feed=$matches[2]');
add_rewrite_rule('(.+)/(feed|rdf|rss|rss2|atom)/?$','index.php?forum=$matches[1]&feed=$matches[2]');
// one rule to handle paging of posts in the taxo
add_rewrite_rule('(.+)/page/?([0-9]{1,})/?$','index.php?forum=$matches[1]&paged=$matches[2]');
// one rule to show the forum taxo normally
add_rewrite_rule('(.+)/?$', 'index.php?forum=$matches[1]');
}
add_action( 'init', 'test_init' );
Помните, что после добавления этого кода, у Вас должен быть он активный, когда Вы идете, сбрасывают правила постоянной ссылки (путем Сохранения страницы на Настройках-> Постоянные ссылки)!
После того, как Вы сбросили правила и сохранили к базе данных, затем / независимо от того, что должно перейти к Вашей forum=whatever странице таксономии.
Перепишите правила, действительно не являются настолько трудными, если Вы понимаете регулярные выражения. Я использую этот код для помощи мне при отладке их:
function test_foot() {
global $wp_rewrite;
echo '<pre>';
var_dump($wp_rewrite->rules);
echo '</pre>';
}
add_action('wp_footer','test_foot');
Таким образом, я вижу текущие правила сразу на моей странице. Просто помните, что, учитывая любой URL, система запускается наверху правил и понижается через них, пока это не находит тот, который соответствует. Соответствие затем используется для перезаписи запроса в более нормальный взгляд? key=value установлен. Те ключи анализируются в то, что входит в объект WP_Query. Простой.
Править: Примечание стороны, этот метод будет, вероятно, только работать, если Ваша нормальная пользовательская структура сообщения запустится с чего-то, что не является вместилищем, как %category % или некоторая такая подобная вещь. Необходимо запустить его со статической строки или числового, как %year %. Это должно предотвратить его, ловя Ваш URL, прежде чем это доберется до Ваших правил.
Вы не сможете сделать это использование один только WP_Rewrite, так как это не может различать краткие заголовки термина и человеко-понятные урлы.
Необходимо также сцепиться в 'запрос' и предотвратить эти 404 путем установки var запроса сообщения вместо таксономии один.
Что-то вроде этого:
function fix_post_request( $request ) {
$tax_qv = 'forum';
$cpt_name = 'post';
if ( !empty( $request[ $tax_qv ] ) ) {
$slug = basename( $request[ $tax_qv ] );
// if this would generate a 404
if ( !get_term_by( 'slug', $slug, $tax_qv ) ) {
// set the correct query vars
$request[ 'name' ] = $slug;
$request[ 'post_type' ] = $cpt_name;
unset( $request[$tax_qv] );
}
}
return $request;
}
add_filter( 'request', 'fix_post_request' );
Обратите внимание, что таксономия должна быть определена перед типом сообщения.
Это было бы хорошим временем, чтобы указать, что наличие таксономии и типа сообщения с тем же var запроса является Плохой Идеей.
Кроме того, Вы не сможете достигнуть сообщений, которые имеют тот же краткий заголовок как одно из условий.
Я смотрел бы на код высокоуровневого плагина кошек:
http://fortes.com/projects/wordpress/top-level-cats/
Вы могли легко адаптировать это так, это ищет Ваш пользовательский краткий заголовок таксономии путем изменения
$category_base = get_option('category_base');
на строке 74 к чему-то как подобный:
$category_base = 'forums';
Я предложил бы смотреть на Пользовательский плагин Постоянных ссылок Сообщения. У меня нет времени для тестирования прямо сейчас, но оно может помочь с ситуацией.
%forum%
, который является точно, чего я стараюсь избегать...
– onetrickpony
18.02.2011, 00:14
Так как я - знакомое с Вашим другим вопросом, я отвечу этим в памяти.
Я не протестировал это вообще, но это могло бы работать при выполнении этого однажды прямо после регистрации всего permastructs, который Вы хотите.:
class RRSwitcher {
var $rules;
function RRSwitcher(){
add_filter( 'topic_rewrite_rules', array( $this, 'topics' ) );
add_filter( 'rewrite_rules_array', array( $this, 'rules' ) );
}
function topics( $array ){
$this->rules = $array;
return array();
}
function rules( $array ){
return array_merge( (array)$array, (array)$this->rules );
}
}
$RRSwitcher = new RRSwitcher();
global $wp_rewrite;
$wp_rewrite->use_verbose_rules = true;
$wp_rewrite->flush_rules();
Что это делает: это удаляет переписать правила, сгенерированные из постоянной ссылки тем от нормального потока массива правил, и повторно объединяет их в конце массива. Это препятствует тем правилам вмешаться в любого другого, переписывают правила. Затем, это вызывает подробный, переписывают правила (каждая страница получает отдельное правило с определенным регулярным выражением). Это препятствует тому, чтобы страницы вмешались в правила Вашей темы. Наконец, это выполняется, твердый сброс (удостоверьтесь, что Ваш .htaccess файл перезаписываем, иначе это не будет работать), и сохраняет очень большой очень сложный массив, переписывают правила.
Это удаляет краткий заголовок типа путем добавления определенного правила для каждой пользовательской полосы набора сообщения.
Не уверенный, если это будет работать на taxonomies, но он работал на пользовательские типы сообщения
Хотя это не обновлялось в течение 2 лет, ниже плагина работал на меня: http://wordpress.org/plugins/remove-slug-from-custom-post-type/
К вашему сведению я выполняю WP 3.9.1
с типами WP 1.5.7
'forum'
таксономия однако, я пересмотрю его для работы позже сегодня... @don de lion – MikeSchinkel 23.02.2011, 14:58'forums'
вместо'forum'
? Вы ожидаете URL, которые связываются с этими страницами для изменения (если да, неудивительный, мой код не обращается к печати URL, только маршрутизации URL.) – MikeSchinkel 24.02.2011, 21:38site/rootforum/
работы, ноsite/rootforum/subforum/
не делает (404 ошибки)... – onetrickpony 24.02.2011, 21:56