Пользовательская таксономия для определенного произвольного типа записи

5 июл. 2012 г., 13:22:29
Просмотры: 138K
Голосов: 36

Я хочу создать пользовательскую таксономию, которая работает аналогично тому, как категории работают с записями по умолчанию (на основе структуры постоянных ссылок /%category%/%postname%/), чтобы записи в произвольных типах записей отображались как www.example.com/custom-post-type/custom-taxonomy-name/post-name Также я хочу, чтобы метабокс категорий появлялся только при добавлении новой записи по умолчанию, а не при добавлении новой записи в произвольном типе записи, и чтобы метабокс пользовательской таксономии появлялся только при добавлении новой записи в произвольном типе записи, а не при добавлении новой записи по умолчанию.

0
Все ответы на вопрос 2
5
58

Прежде всего, если вы хотите показывать метабокс таксономии только для вашего пользовательского типа записи, зарегистрируйте таксономию только для этого типа записи, передав его имя в качестве аргумента в функцию register_taxonomy(). Это приведёт к тому, что метабокс таксономии будет отображаться только для пользовательского типа записи. Если вы не хотите показывать метабокс категорий для вашего типа записи, удалите категорию из аргументов при регистрации типа записи и вместо этого укажите слаг вашей таксономии, например: 'taxonomies' => array( 'post_tag', 'your_taxonomy_name'). Вот код, как я добился этого.

Я зарегистрировал пользовательскую таксономию с слагом "themes_categories" для пользовательского типа записи "themes":

function themes_taxonomy() {
    register_taxonomy(
        'themes_categories',  // Имя таксономии. Должно быть в формате слага (без заглавных букв и пробелов).
        'themes',             // Имя типа записи
        array(
            'hierarchical' => true,
            'label' => 'Магазин тем', // Отображаемое имя
            'query_var' => true,
            'rewrite' => array(
                'slug' => 'themes',    // Управляет базовым слагом перед каждым термином
                'with_front' => false  // Не отображать базу категории перед термином
            )
        )
    );
}
add_action( 'init', 'themes_taxonomy');

Затем, чтобы изменить постоянную ссылку, я создал следующую функцию:

function filter_post_type_link( $link, $post ) {
    if ( $post->post_type !== 'themes' )
        return $link;

    if ( $cats = get_the_terms($post->ID, 'themes_categories') )
        $link = str_replace('%themes_categories%', array_pop($cats)->slug, $link);

    return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);

Затем я зарегистрировал пользовательский тип записи с слагом "themes":

// Регистрация пользовательского типа записи Themes
add_action( 'init', 'register_themepost', 20 );
function register_themepost() {
    $labels = array(
        'name' => _x( 'Темы', 'my_custom_post','custom' ),
        'singular_name' => _x( 'Тема', 'my_custom_post', 'custom' ),
        'add_new' => _x( 'Добавить новую', 'my_custom_post', 'custom' ),
        'add_new_item' => _x( 'Добавить новую тему', 'my_custom_post', 'custom' ),
        'edit_item' => _x( 'Редактировать тему', 'my_custom_post', 'custom' ),
        'new_item' => _x( 'Новая тема', 'my_custom_post', 'custom' ),
        'view_item' => _x( 'Просмотреть тему', 'my_custom_post', 'custom' ),
        'search_items' => _x( 'Искать темы', 'my_custom_post', 'custom' ),
        'not_found' => _x( 'Тем не найдено', 'my_custom_post', 'custom' ),
        'not_found_in_trash' => _x( 'Тем в корзине не найдено', 'my_custom_post', 'custom' ),
        'parent_item_colon' => _x( 'Родительская тема:', 'my_custom_post', 'custom' ),
        'menu_name' => _x( 'Темы', 'my_custom_post', 'custom' ),
    );

    $args = array(
        'labels' => $labels,
        'hierarchical' => false,
        'description' => 'Пользовательские записи тем',
        'supports' => array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', 'comments', 'revisions', 'post-formats', 'custom-fields' ),
        'taxonomies' => array( 'post_tag','themes_categories'),
        'show_ui' => true,
        'show_in_menu' => true,
        'menu_position' => 5,
        'menu_icon' => get_stylesheet_directory_uri() . '/functions/panel/images/catchinternet-small.png',
        'show_in_nav_menus' => true,
        'publicly_queryable' => true,
        'exclude_from_search' => false,
        'query_var' => true,
        'can_export' => true,
        'rewrite' => array( 'slug' => 'themes/%themes_categories%', 'with_front' => FALSE ),
        'public' => true,
        'has_archive' => 'themes',
        'capability_type' => 'post'
    );
    register_post_type( 'themes', $args ); // максимум 20 символов, без заглавных букв и пробелов
}

Есть несколько моментов, которые нужно помнить при регистрации пользовательского типа записи. Измените параметр "has_archive" на слаг типа записи, а в rewrite укажите слаг в формате 'slug' => 'custom_post_type_slug/%taxonomy_slug%.

Теперь при добавлении записи вы увидите постоянную ссылку в формате http://www.example.com/wordpress/themes/%themes_categories%/post-name/. Если таксономия для записи не выбрана, ссылка останется в таком же формате, что приведёт к ошибке.

Чтобы исправить это, создадим термин по умолчанию в таксономии (аналогично "Без рубрики" в категориях).

Добавьте в functions.php:

function default_taxonomy_term( $post_id, $post ) {
    if ( 'publish' === $post->post_status ) {
        $defaults = array(
            'themes_categories' => array('other'),
        );
        $taxonomies = get_object_taxonomies( $post->post_type );
        foreach ( (array) $taxonomies as $taxonomy ) {
            $terms = wp_get_post_terms( $post_id, $taxonomy );
            if ( empty($terms) && array_key_exists( $taxonomy, $defaults ) ) {
                wp_set_object_terms( $post_id, $defaults[$taxonomy], $taxonomy );
            }
        }
    }
}
add_action( 'save_post', 'default_taxonomy_term', 100, 2 );

Теперь, если таксономия не выбрана, ссылка автоматически станет http://www.example.com/wordpress/themes/other/post-name/.

Наконец, не забудьте сбросить правила ЧПУ, нажав "Сохранить изменения" в настройках постоянных ссылок в админ-панели WordPress, иначе будет перенаправление на 404 ошибку. Надеюсь, это поможет вам.

5 июл. 2012 г. 17:52:03
Комментарии

Привет, у меня была проблема... когда мы выводим ссылку на архив таксономии с помощью echo get_the_term_list( $post->ID, $taxonomy, '', ', ', '' ); то ссылка отображается как www.example.com/taxonomy-term, а не www.example.com/themes/taxonomy-term. Думаю, нам нужно написать правило для HTACCESS.

Saurabh Goel Saurabh Goel
6 июл. 2012 г. 16:49:34

+1, отличное объяснение, следовал шаг за шагом и всё работает, протестировано на WordPress 3.4.2

TechAurelian TechAurelian
23 окт. 2012 г. 22:27:22

Мне было интересно: нужно ли добавлять пользовательскую таксономию в массив таксономий при регистрации типа записи? Потому что, кажется, это работает и без добавления туда (если вы уже регистрируете таксономию для этого типа записи). Просто любопытно.

trainoasis trainoasis
8 мар. 2017 г. 09:52:43

Попробовал это с плагином CPT UI, продолжая использовать ваш rewrite для изменения URL. Все выглядит хорошо, URL-адреса верные, и я сбросил постоянные ссылки, но сами записи выдают 404. :( РЕДАКТИРОВАТЬ: неважно. Я прошел и убрал Hierarchical из таксономии, а также убедился, что сохраняю все в правильном порядке, и теперь записи, кажется, работают. Ура!

Garconis Garconis
17 мая 2018 г. 22:53:26

Возможно, сейчас полезно отметить, что функция 'register_taxonomy' требует, чтобы аргумент 'show_in_rest' был TRUE для использования нового блочного редактора WordPress.

Lee Lee
8 мая 2024 г. 18:30:24
0

Например, регистрация пользовательской таксономии MY_NEW_CARSS для пользовательских типов записей:

$my_taxon_name  = 'MY_NEW_CARSS';
$my_post_types  = array('SUB_CAT_1','SUB_CAT_2','SUB_CAT_3');


//РЕГИСТРАЦИЯ ПОЛЬЗОВАТЕЛЬСКОЙ ТАКСОНОМИИ ( http://codex.wordpress.org/Function_Reference/register_taxonomy )
//Если вы хотите зарегистрировать ИЕРАРХИЧЕСКИЙ (с родительскими элементами) тип записи, прочтите это предупреждение: https://codex.wordpress.org/Function_Reference/register_post_type#hierarchical
add_action( 'init', 'my_f32' ); function my_f32() { 
    register_taxonomy( $GLOBALS['my_taxon_name'], array(), 
        array( 
            'label'=>$GLOBALS['my_taxon_name'],     'public'=>true, 'show_ui'=>true,  'show_admin_column'=>true,   'query_var'=>true,
            'hierarchical'=>true,   'rewrite'=>array('with_front'=>true,'hierarchical'=>true),  
             ));
}

//РЕГИСТРАЦИЯ ПОЛЬЗОВАТЕЛЬСКОГО ТИПА ЗАПИСИ ( http://codex.wordpress.org/Function_Reference/register_post_type )
add_action( 'init', 'myf_63' );function myf_63() { 

    foreach ($GLOBALS['my_post_types'] as $each_Type)       {
            register_post_type( $each_Type, 
                array( 
                    'label'=>$each_Type,     'labels' => array('name'=>$each_Type.' страницы', 'singular_name'=>$each_Type.' страница'),        'public' => true,   'publicly_queryable'=> true,      'show_ui'=>true,      'capability_type' => 'post',      'has_archive' => true,      'query_var'=> true,     'can_export' => true,                   //'exclude_from_search' => false,     'show_in_nav_menus' => true,  'show_in_menu' => 'edit.php?post_type=page',//true,     'menu_position' => 5,
                    'hierarchical' =>true,
                    'supports' =>array( 'page-attributes', 'title', 'editor', 'thumbnail' ), 
                    'rewrite' => array('with_front'=>true, ),     //    'rewrite' => array("ep_mask"=>EP_PERMALINK ...) OR    'permalink_epmask'=>EP_PERMALINK, 
                ));

            register_taxonomy_for_object_type('category',$each_Type);       //стандартные категории
            register_taxonomy_for_object_type($GLOBALS['my_taxon_name'] ,$each_Type);   //Пользовательские категории
    }
}
25 июл. 2015 г. 21:32:38