Правила перезаписи WordPress для пользовательских типов записей и таксономий
Раньше я находил здесь много полезной информации через Google, решая различные проблемы. Мой вопрос касается подробных правил перезаписи, которые использует WordPress.
Я создал пользовательский тип записей под названием project и зарегистрировал пользовательскую таксономию под названием projects. Всё работает отлично, кроме настроек slug для перезаписи, так как они конфликтуют - скорее всего из-за правил перезаписи.
Вот структура URL, которую я хочу получить:
example.com/work/%taxonomy%/%post_name%/
(для записей)example.com/work/%taxonomy%/
(список записей, принадлежащих определённому термину таксономии)example.com/work/
(переходит на page-work.php, который включает taxonomy.php для отображения всех записей этой таксономии)
Вот код, который у меня есть сейчас, но мне нужна помощь с написанием правил WP_Rewrite, так как я застрял на этом моменте.
$labels = array(
'name' => _x('Проекты', 'общее название типа записи'),
'singular_name' => _x('Проект', 'название типа записи в единственном числе'),
'add_new' => _x('Добавить новый', 'элемент проекта'),
'add_new_item' => __('Добавить новый проект'),
'edit_item' => __('Редактировать проект'),
'new_item' => __('Новый проект'),
'view_item' => __('Просмотреть проект'),
'search_items' => __('Поиск проектов'),
'not_found' => __('Ничего не найдено'),
'not_found_in_trash' => __('В корзине ничего не найдено'),
'parent_item_colon' => ''
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'hierarchical' => true,
'rewrite' => array('slug'=>'work', 'with_front'=>false),
'show_ui' => true,
'_builtin' => false, // Это пользовательский тип записи, не встроенный!
'capability_type' => 'post',
'query_var' => "project", // Это идёт в схему WP_Query
'menu_position' => null,
'supports' => array('title','editor','thumbnail', 'comments', 'author', 'excerpt')
);
register_post_type('project' , $args);
// Таксономия проектов
register_taxonomy('projects', array('project'), array(
'public' => true,
'hierarchical' => true,
'label' => 'Категории проектов',
'singular_label' => 'Категория проекта',
'query_var' => true,
'rewrite' => array('slug'=>'work', 'with_front'=>false, 'hierarchical'=>true)
)
);
Большое спасибо за вашу помощь! :-)
Надеюсь, это решит вашу проблему
function my_custom_post_type() {
$labels = array(
'name' => _x('Проекты', 'название типа записи'),
'singular_name' => _x('Проект', 'название типа записи в единственном числе'),
'add_new' => _x('Добавить новый', 'элемент проекта'),
'add_new_item' => __('Добавить новый проект'),
'edit_item' => __('Редактировать проект'),
'new_item' => __('Новый проект'),
'view_item' => __('Просмотреть проект'),
'search_items' => __('Искать проекты'),
'not_found' => __('Ничего не найдено'),
'not_found_in_trash' => __('В корзине ничего не найдено'),
'parent_item_colon' => '',
'menu_name' => 'Проекты'
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'hierarchical' => false,
'has_archive' => true,
'rewrite' => array('slug'=>'work', 'with_front'=>false),
'show_ui' => true,
'_builtin' => false, // Это пользовательский тип записи, не встроенный!
'capability_type' => 'post',
'query_var' => true, // Это идет в схему WP_Query
'menu_position' => null,
'supports' => array('title','editor','thumbnail', 'comments', 'author', 'excerpt')
);
register_post_type( 'work' , $args );
}
function my_custom_taxonomies() {
$labels = array(
'name' => __( 'Таксономия', 'общее название таксономии' ),
'singular_name' => __( 'Таксономия', 'название таксономии в единственном числе' ),
'search_items' => __( 'Искать таксономию' ),
'all_items' => __( 'Все таксономии' ),
'parent_item' => __( 'Родительская таксономия' ),
'parent_item_colon' => __( 'Родительская таксономия:' ),
'edit_item' => __( 'Редактировать таксономию' ),
'update_item' => __( 'Обновить таксономию' ),
'add_new_item' => __( 'Добавить новую таксономию' ),
'new_item_name' => __( 'Новое название таксономии' ),
'menu_name' => __( 'Таксономия' ),
);
register_taxonomy( 'taxonomy', array('work'), array (
'labels' => $labels,
'hierarchical' =>false,
'show_ui' => true,
'rewrite' => array( 'slug' => 'work/taxonomy'),
'query_var' => true,
'show_in_nav_menus' => true,
'public' => true,
));
}
add_action('init', 'my_custom_post_type', 0);
add_action('init', 'my_custom_taxonomies', 10);
Вам нужно создать archive-work.php (архив вашего типа записи) и taxonomy.php, который будет использоваться для отображения архива вашей пользовательской таксономии.

У меня была такая же проблема, и после долгих мучений я пришел к этому решению.
Просто добавьте это в ваш код
global $wp_rewrite;
$wp_rewrite->flush_rules();
function my_custom_post_type() {
$labels = array(
'name' => _x('Проекты', 'post type general name'),
'singular_name' => _x('Проект', 'post type singular name'),
'add_new' => _x('Добавить новый', 'project item'),
'add_new_item' => __('Добавить новый проект'),
'edit_item' => __('Редактировать проект'),
'new_item' => __('Новый проект'),
'view_item' => __('Просмотреть проект'),
'search_items' => __('Искать проекты'),
'not_found' => __('Ничего не найдено'),
'not_found_in_trash' => __('Ничего не найдено в корзине'),
'parent_item_colon' => '',
'menu_name' => 'Проекты'
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'hierarchical' => false,
'has_archive' => true,
'rewrite' => array('slug'=>'work', 'with_front'=>false),
'show_ui' => true,
'_builtin' => false, // Это пользовательский тип записи, не встроенный!
'capability_type' => 'post',
'query_var' => true, // Это идет в схему WP_Query
'menu_position' => null,
'supports' => array('title','editor','thumbnail', 'comments', 'author', 'excerpt')
);
register_post_type( 'work' , $args );
global $wp_rewrite;
$wp_rewrite->flush_rules(); // это должно помочь
}

$wp_rewrite->flush_rules() не следует запускать так часто, эта функция должна вызываться только на хуках активации или деактивации, либо как можно реже. Об этом сказано здесь: http://codex.wordpress.org/Rewrite_API/flush_rules Кроме того, это практически та же самая функция, что и эта: http://codex.wordpress.org/Function_Reference/flush_rewrite_rules

Кстати, вот как я реализовал это: http://pastebin.com/k7QvxKLi

@Jared Спасибо за замечание, но я не смог понять, как реализовать это, когда код интегрирован в нашу тему (а не через плагин). Пожалуйста, подскажите.

В этом случае код нужно поместить в файл functions.php
. Код для плагина и темы абсолютно одинаков, единственное отличие в том, что в темах он всегда должен быть в файле functions.php
или в файле, который подключается в functions.php

Более подробное объяснение можно найти в другой статье, но вот основные части, которые нужно добавить:
Зарегистрируйте свои таксономии и пользовательские типы записей как обычно. Убедитесь, что ваш слаг rewrite для таксономии - "basename", а для пользовательского типа записи - "basename/%tax_name%".
Объясните WordPress, что делать с "%tax_name%" следующим образом:
function filter_post_type_link($link, $post) { if ($post->post_type != 'custom_post_type_name') return $link; if ($cats = get_the_terms($post->ID, 'taxonomy_name')) { // Заменяем %taxonomy_name% на ID последнего элемента из массива категорий $link = str_replace('%taxonomy_name%',array_pop($cats)->term_id, $link); // см. пользовательскую функцию, определенную ниже } return $link; } add_filter('post_type_link', 'filter_post_type_link', 10, 2);
