Как добиться правильного чпу?

Привет Toster!
На сайте создан custom post type с именем school:
//Добавление произвольного типа записи/custom post type - school
add_action( 'init', 'true_register_school' ); // Использовать функцию только внутри хука init
 
function true_register_school() {
	$labels = array(
		'name' => 'Школа',
		'singular_name' => 'Материал', // админ панель Добавить->Функцию
		'add_new' => 'Добавить материал',
		'add_new_item' => 'Добавить новый материал', // заголовок тега <title>
		'edit_item' => 'Редактировать материал',
		'new_item' => 'Новый материал',
		'all_items' => 'Все материалы',
		'view_item' => 'Просмотр материалов на сайте',
		'search_items' => 'Искать материалы',
		'not_found' =>  'Материалов не найдено.',
		'not_found_in_trash' => 'В корзине нет материалов.',
		'menu_name' => 'Школа' // ссылка в меню в админке
	);
	$args = array(
		'labels' => $labels,
		'public' => true, // благодаря этому некоторые параметры можно пропустить
		'menu_icon' => 'dashicons-admin-users', // иконка корзины
		'menu_position' => 5,
		'has_archive' => true,
		'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'comments'),
		'taxonomies' => array('subjects', 'typedoc', 'klass')
	);
	register_post_type('school',$args);
}

Также у записей custom post type school убран slug. Для создания нормальных урлов записей.
Вместо записей такого вида:
site.ru/school/prezentatsiya-k-uroku-matematiki-3-klass/
Стало так:
site.ru/prezentatsiya-k-uroku-matematiki-3-klass/
/**
 * Remove the slug from published post permalinks. Only affect our custom post type, though.
 */
function gp_remove_cpt_slug( $post_link, $post, $leavename ) {
 
    if ( 'school' != $post->post_type || 'publish' != $post->post_status ) {
        return $post_link;
    }
 
    $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
 
    return $post_link;
}
add_filter( 'post_type_link', 'gp_remove_cpt_slug', 10, 3 );

function gp_parse_request_trick( $query ) {
 
    // Only noop the main query
    if ( ! $query->is_main_query() )
        return;
 
    // Only noop our very specific rewrite rule match
    if ( 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
        return;
    }
 
    // 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
    if ( ! empty( $query->query['name'] ) ) {
        $query->set( 'post_type', array( 'post', 'page', 'school' ) );
    }
}
add_action( 'pre_get_posts', 'gp_parse_request_trick' );


К custom post type создано и привязано 3 taxonomy (subjects, typedoc, klass):
/// хук через который подключается функция
/// регистрирующая новые таксономии (create_subjects_taxonomies)
add_action( 'init', 'create_subjects_taxonomy', 0 );


// функция, создающая 1 новую таксономию "subjects" для постов типа "school"
function create_subjects_taxonomy(){
    
    // Добавляем древовидную таксономию 'subjects' (как категории)
    register_taxonomy('subjects', array('school'), array(
	   'hierarchical' => true,
	   'labels' => array(
             // определяем заголовки для 'subjects'
	           'name' => 'Предметы',
	           'singular_name' => 'Предметы',
	           'search_items' =>  'Найти предметы',
	           'all_items' => 'Все предметы',
	           'parent_item' => null,
                //текст для родительского элемента таксономии. Этот аргумент не используется для не древовидных таксономий. По умолчанию null
	           'parent_item_colon' => null,
                //текст для родительского элемента таксономии, тоже что и parent_item но с двоеточием в конце. По умолчанию нет или
	           'edit_item' => 'Редактировать предмет',
	           'update_item' => 'Обновить предмет',
	           'add_new_item' => 'Добавить новый предмет',
	           'new_item_name' => 'Название нового предмета',
	           'menu_name' => 'Предметы'
       ),
       'public' => true, 
        /* каждый может использовать таксономию, либо
        только администраторы, по умолчанию - true */
       'show_in_nav_menus' => true,
        /* добавить на страницу создания меню */
	   'show_ui' => true,
        /* добавить интерфейс создания и редактирования */
       'show_tagcloud' => true,
        /* нужно ли разрешить облако тегов для этой таксономии */
	   'query_var' => true,
        /* разрешено ли использование query_var, также можно 
        указать строку, которая будет использоваться в качестве 
        него, по умолчанию - имя таксономии */
	   'rewrite' => array( 
           /* настройки URL пермалинков */
           'slug' => 'school', // ярлык
           'hierarchical' => true // разрешить вложенность, если false - то не будет правильной иерархии категорий
            ),
    ));
    
}

/// хук через который подключается функция
/// регистрирующая новые таксономии (create_typedoc_taxonomies)
add_action( 'init', 'create_typedoc_taxonomy', 0 );


// функция, создающая 1 новую таксономию "typedoc" для постов типа "school"
function create_typedoc_taxonomy(){
    
    // Добавляем древовидную таксономию 'typedoc' (как категории)
    register_taxonomy('typedoc', array('school'), array(
	   'hierarchical' => true,
	   'labels' => array(
             // определяем заголовки для 'typedoc'
	           'name' => 'Тип документа',
	           'singular_name' => 'Документы',
	           'search_items' =>  'Найти документы',
	           'all_items' => 'Все документы',
	           'parent_item' => null,
                //текст для родительского элемента таксономии. Этот аргумент не используется для не древовидных таксономий. По умолчанию null
	           'parent_item_colon' => null,
                //текст для родительского элемента таксономии, тоже что и parent_item но с двоеточием в конце. По умолчанию нет или
	           'edit_item' => 'Редактировать документ',
	           'update_item' => 'Обновить документ',
	           'add_new_item' => 'Добавить новый документ',
	           'new_item_name' => 'Название нового документа',
	           'menu_name' => 'Тип документа'
       ),
       'public' => true, 
        /* каждый может использовать таксономию, либо
        только администраторы, по умолчанию - true */
       'show_in_nav_menus' => true,
        /* добавить на страницу создания меню */
	   'show_ui' => true,
        /* добавить интерфейс создания и редактирования */
       'show_tagcloud' => true,
        /* нужно ли разрешить облако тегов для этой таксономии */
	   'query_var' => true,
        /* разрешено ли использование query_var, также можно 
        указать строку, которая будет использоваться в качестве 
        него, по умолчанию - имя таксономии */
	   'rewrite' => array( 
           /* настройки URL пермалинков */
           'slug' => 'school', // ярлык
           'hierarchical' => true // разрешить вложенность, если false - то не будет правильной иерархии категорий
            ),
    ));
    
}

/// хук через который подключается функция
/// регистрирующая новые таксономии (create_klass_taxonomies)
add_action( 'init', 'create_klass_taxonomy', 0 );


// функция, создающая 1 новую таксономию "klass" для постов типа "school"
function create_klass_taxonomy(){
    
    // Добавляем древовидную таксономию 'klass' (как категории)
    register_taxonomy('klass', array('school'), array(
	   'hierarchical' => true,
	   'labels' => array(
             // определяем заголовки для 'klass'
	           'name' => 'Класс',
	           'singular_name' => 'Классы',
	           'search_items' =>  'Найти классы',
	           'all_items' => 'Все классы',
	           'parent_item' => null,
                //текст для родительского элемента таксономии. Этот аргумент не используется для не древовидных таксономий. По умолчанию null
	           'parent_item_colon' => null,
                //текст для родительского элемента таксономии, тоже что и parent_item но с двоеточием в конце. По умолчанию нет или
	           'edit_item' => 'Редактировать класс',
	           'update_item' => 'Обновить класс',
	           'add_new_item' => 'Добавить новый класс',
	           'new_item_name' => 'Название нового класса',
	           'menu_name' => 'Класс'
       ),
       'public' => true, 
        /* каждый может использовать таксономию, либо
        только администраторы, по умолчанию - true */
       'show_in_nav_menus' => true,
        /* добавить на страницу создания меню */
	   'show_ui' => true,
        /* добавить интерфейс создания и редактирования */
       'show_tagcloud' => true,
        /* нужно ли разрешить облако тегов для этой таксономии */
	   'query_var' => true,
        /* разрешено ли использование query_var, также можно 
        указать строку, которая будет использоваться в качестве 
        него, по умолчанию - имя таксономии */
	   'rewrite' => array( 
           /* настройки URL пермалинков */
           'slug' => 'school', // ярлык
           'hierarchical' => true // разрешить вложенность, если false - то не будет правильной иерархии категорий
            ),
    ));
    
}


Таксономия subjects для сортировки по предметам:
Математика, русский язык, физика, химия, биология, география, история и т.д.
Таксономия typedoc для сортировки по по типу файла:
Например: презентация, конспект, видеоурок и т.д.
Таксономия klass для сортировки по классам:
1 класс, 2 класс, 3 класс, 4 класс, 5 класс и т.д.

Вопрос:
Как добиться правильного ЧПУ такого вида:
site.ru/school/mathematics/presentations/1_klass/
site.ru/school/russian/videolessons/3_klass/

P.S: Все это нужно для создания фильтра поиска по записям school.
Например пользователь заходит в рубрику предмета математика и сможет выбрать все презентации по математике для 3 класса.
Спасибо!
  • Вопрос задан
  • 645 просмотров
Пригласить эксперта
Ответы на вопрос 3
Slams
@Slams
Не заморачивайтесь с ЧПУ, главное, чтобы в архивах и хлебных крошках иерархия была понятна.

Потом вдруг придется изменить структуру директории, а вы окажетесь привязаны к урлам и придется заморачиваться с 301-ми редиректами.
Ответ написан
Комментировать
Gori4ka
@Gori4ka
WordPress Developer
ну а так я бы на Вашем месте сделал всё в одной древовидной иерархической таксономии. и сделал бы вместо стандартной страницы добавления терминов свою.
Ответ написан
Комментировать
@Karmov69
add_filter('post_type_link', 'betons_permalink', 1, 2);
function betons_permalink( $permalink, $post ){
// выходим если это не наш тип записи: без холдера %taxname%
if( strpos($permalink, '%taxname%') === false )
return $permalink;

// Получаем элементы таксы
$terms = get_the_terms($post, 'taxname');
// если есть элемент заменим холдер
if( ! is_wp_error($terms) && !empty($terms) && is_object($terms[0]) )
$term_slug = array_pop($terms)->slug;
// элемента нет, а должен быть...
else
$term_slug = 'no-taxname';

return str_replace('%taxname%', $term_slug, $permalink );
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы