Создание произвольных типов записей и таксономий

Admin WordPress

Создаём произвольную таксономию для новостей в WordPress. В данной инструкции будет создан новый тип записей «Новости» и функционал для него. В том числе создание новых рубрик (разделов) для Новостей.

Сначала создадим новую таксономию (отдельный список разделов). А затем новый тип записей, отличный от уже существующих Записи и Страницы.

В предыдущем материале уже описывалось создание новой таксономии (категории) для записи в WordPress. Там добавлялись только новые категории. В данном же случае будет создана отдельный тип записей (параллельно стандартным записям) со своими таксономиями (категориями), без привязки к стандартной записи.

В панели администрирования меню WordPress появится новый тип записей и будет выгледеть он следующим образом:

Новую таксономию можно оформить в виде нового плагина для WordPress. Это решение будет более эстетичным. Однако для удобства описания, чтобы всё не городить в одном месте и не усложнять, инструкция ниже будет дана по изменению файла functions.php.

Создание новой таксономии

По аналогии с предыдущей статьёй создаём новую таксономию для WordPress. Однако вместо таксономии для категорий «Имен» будет создана таксономия для категорий «Новости».

// Регистрация новой таксономии:
add_action( 'init', 'create_snews', 0 );
function create_snews () {
$args = array(
    // Название таксономии
    'label' => _x( 'Новости', 'taxonomy general name' ),
   
    // Значения таксономии в админ-панели:
    'labels' => array(
    // Общее название таксономии (множественное число).
    // По умолчанию: 'МеткИ' или 'РубрикИ'
    'name' => _x( 'Новости', 'taxonomy general name' ),
    // Название таксономии (единственное число).
    // По умолчанию: 'МеткА' или 'РубрикА'
    'singular_name' => _x( 'R', 'taxonomy singular name' ),
    // Название таксономии в пункте меню.
    'menu_name' => __( 'Новостные рубрики' ),
    // По умолчанию: 'Все метки' или 'Все рубрики'
    'all_items' => __( 'Все Новости' ),
    // Текст изменения таксономии на странице редактирования.
    // По умолчанию: 'Изменить метку' или 'Изменить рубрику'
    'edit_item' => __( 'Изменить новость' ),
    // Текст в админ-панели на странице редактирования данной таксономии.
    // По умолчанию: 'Просмотреть метку' или 'Просмотреть рубрику'
    'view_item' => __( 'Просмотреть Новости' ),
    // Текст обновления таксономии во вкладке свойства.
    // По умолчанию: 'Обновить метку' или 'Обновить рубрику'
    'update_item' => __( 'Обновить новость' ),
    // Текст добавления новой таксономии при ее создании.
    // По умолчанию: 'Добавить новую метку' или 'Добавить новую рубрику'
    'add_new_item' => __( 'Добавить новость' ),
    // Название таксономии при ее создании и редактировании.
    // По умолчанию: 'Название'
    'new_item_name' => __( 'Название' ),
    // Текст родительской таксономии при создании и редактировании.
    // Для древовидных таксономий.
    // По умолчанию: Родительская.
    'parent_item' => __( 'Родительская' ),
    // То же, что и parent_item, но с добавлением двоеточия.
    // По умолчанию: 'Родительская:'
    'parent_item_colon' => __( 'Родительская:' ),
    // Текст в кнопке поиска на странице всех таксономий.
    // По умолчанию: 'Поиск меток' или 'Поиск рубрик'
    'search_items' => __( 'Поиск новости' ),
   
    // ЧЕТЫРЕ НИЖНИХ параметра НЕ используется для древовидных таксономий:
    // Надпись популярных таксономий (на странице всех таксономий).
    // По умолчанию: Популярные метки или null.
    'popular_items' => null,
    // Надпись разделения таксономий запятыми в метабоксе.
    // По умолчанию: Метки разделяются запятыми или null.
    'separate_items_with_commas' => null,
    // Надпись добавления или удаления таксономий в метабоксе когда JavaScript отключен.
    // По умолчанию: Добавить или null.
    'add_or_remove_items' => null,
    // Текст выбора из часто используемых таксономий в метабоксе.
    // По умолчанию: Выбрать из часто используемых или null.
    'choose_from_most_used' => null,
   
    // Текст в случае, если запрашиваемая таксономия не найдена.
    // По умолчанию: 'Меток не найдено. или 'Рубрик не найдено.
    'not_found' => __( 'Новость не найдена.' ),
    ),
    // Если true, то таксономия становится доступной для использования.
    'public' => true,
    // Доступность таксономии для управления в админ-панели, но не показывает ее в меню.
    // По умолчанию: 'public'.
    'show_ui' => true,
    // Показывать таксономию в админ-меню.
    // Значение аргумента 'show_ui' должно быть true.
    // По умолчанию: значение аргумента 'show_ui'.
    'show_in_menu' => true,
    // Добавляет или исключает таксономию в навигации сайта "Внешний вид -> Меню"
    // По умолчанию: 'public'.
    'show_in_nav_menus' => true,
    // Позволяет виджет 'Облако меток' использовать в таксономии.
    // По умолчанию: 'show_ui'.
    'show_tagcloud' => true,
    // Показ таксономии в меню быстрого доступа.
    // По умолчанию: 'show_ui'.
    'show_in_quick_edit' => true,
    // Обеспечивает показ метабокса с таксономией в записи. По умолчанию: null.
    'meta_box_cb' => null,
    // Позволяет автоматическое создание столбцов таксономии в таблице ассоциативных типов постов.
    // По умолчанию: false.
    'show_admin_column' => false,
    // Подключает описание таксономии в таблице со всеми таксономиями. По умолчанию: ''
    'description' => '',
    // Делает таксономию древовидной как рубрики или недревовидной как метки. По умолчанию: false.
    'hierarchical' => true,
    // Название функции, вызываемая после обновления ассоциативных типов объектов записи (поста)
    // Действует во многом как хук.
    // По умолчанию: ''.
    'update_count_callback' => '',
    // Значение запроса. По умолчанию: true.
    'query_var' => true,
   
    // Перезапись URL. По умолчанию: true.
    'rewrite' => array(
    // Текст в ЧПУ. По умолчанию: название таксономии.
    'slug' => 'snews',
    // Позволяет ссылку добавить к базовому URL.
    'with_front' => false,
    // Использовать (true) или не использовать (false) древовидную структуру ссылок.
    // По умолчанию: false.
    'hierarchical' => true,
    // Перезаписывает конечное значение таксономии. По умолчанию: EP_NONE.
    'ep_mask' => EP_NONE,
),
   
/*
    // Массив полномочий зарегестрированных пользователей:
    'capabilities' => array(
    'manage_terms' => 'manage_resource',
    'edit_terms'   => 'manage_categories',
    'delete_terms' => 'manage_categories',
    'assign_terms' => 'edit_posts',
),
*/

    // Должна ли таксономия запоминать порядок, в котором посты были созданы.
    // По умолчанию: null.
    'sort' => null,
    // Является ли таксономия собственной или встроенной.
    // Рекомендация: не использовать этот аргумент при регистрации собственной таксономии.
    // По умолчанию: false.
    '_builtin' => false,
);
    // Названия типов записей к которым будет привязана таксономия
    register_taxonomy( 'snews', array('news'), $args );
}

Создание шаблона для новой таксономии

Для отображения новых категорий в корневой части своего шаблона WordPress создаём файл taxonomy-snews.php. Туда вносим содержимое файла archive.php с нужными изменениями.

Прописываем к нему пути в файле archive.php:

// категория таксономия
elseif (is_tax(snews) ) {
    get_template_part( '/taxonomy-snews' );
}

Как интегрируется этот код в общую структуру файла archive.php есть в предыдущей статье в самом низу.

Создание произвольного типа записи

Теперь создадим произвольный тип записи, которым будет являться «Новости». Для этого в файл functions.php нужно добавить следующий код:

// Регистрация пользовательского типа записи:
add_action( 'init', 'register_post_news', 0 );
function register_post_news() {
$args = array(
    // Название пользовательского типа записи во множественном числе.
    // По умолчанию: значение аргумента 'name' массива 'labels'.
    'label'  => _x( 'Новости', 'Post Type General Name', 'text_domain' ),
    'labels' => array(
    // Общее название пользовательского типа записи во множественном числе.
    // Переопределяет значение 'label'.
    // По умолчанию: 'Записи' или 'Страницы'
    'name' => _x( 'Новости', 'Post Type General Name', 'text_domain' ),
    // Название пользовательского типа записи в единственном числе.
    // По умолчанию: 'Запись' или 'Страница'
    'singular_name' => _x( 'Новость', 'Post Type Singular Name', 'text_domain' ),
    // Текст добавления нового объекта типа записи в разделе 'Записи'/'Страницы' в админ-панели.
    // По умолчанию: 'Добавить новую'
    'add_new' => __( 'Добавить новость', 'text_domain' ),
    // Текст добавления нового объекта типа записи на странице создания.
    // По умолчанию: 'Добавить запись' или 'Добавить страницу'
    'add_new_item' => __( 'Добавить новость', 'text_domain' ),
    // Текст редактирования объекта типа записи на странице редактирования.
    // По умолчанию: 'Редактировать запись' или Редактировать страницу
    'edit_item' => __( 'Редактировать новость', 'text_domain' ),
    // Текст новой объекта типа записи.
    // По умолчанию: Новая запись или Новая страница
    'new_item' => __( 'Новая новость', 'text_domain' ),
    // Текст просмотра типа записи в админ-баре.
    // По умолчанию: 'Просмотреть запись' или 'Просмотреть страницу'
    'view_item' => __( 'Просмотреть новость', 'text_domain' ),
    // Текст на кнопке поиска объектов данного типа записи.
    // По умолчанию: 'Поиск записей' или 'Поиск страниц'
    'search_items' => __( 'Поиск новостей', 'text_domain' ),
    // Текст в случае отрицательного результата поиска объектов данного типа записи.
    // По умолчанию: 'Записей не найдено' или 'Страниц не найдено'
    'not_found' => __( 'Новостей не найдено', 'text_domain' ),
    // Текст в случае отрицательного результата поиска объектов данного типа записи в корзине.
    // По умолчанию: 'Записей в корзине не найдено' или 'Страниц в корзине не найдено'
    'not_found_in_trash' => __( 'Новостей в корзине не найдено', 'text_domain' ),
    // Текст при выборе родительской страницы.
    // Данный аргумент применяется только для древовидных типов записи.
    // По умолчанию: __( 'Родительская:', 'text_domain' ).
    'parent_item_colon' => null,
    // Текст всех объектов типа записи в подменю.
    // По умолчанию: 'Все записи' или 'Все страницы
    'all_items' => __( 'Все новости', 'text_domain' ),
    // Текст архивов типа записи.
    // По умолчанию: 'Архивы записей' или 'Архивы страниц'
    'archives' => __( 'Архивы новостей', 'text_domain' ),
    // Текст добавления медиафайлов в объект типа записи во вкладке 'Добавить медиазапись'.
    // По умолчанию: 'Вставить в запись' или 'Вставить в страницу'
    'insert_into_item' => __( 'Вставить в новость', 'text_domain' ),
    // Используется при просотре медиафайлов, прикрепленных к данному типу записи.
    // По умолчанию: _x( 'Загружен для:', 'text_domain' ).
    'uploaded_to_this_item' => _x( 'Загружен для:', 'text_domain' ),
    // Текст в метабоксе миниатюры на странице редактирования типа записи.
    // По умолчанию: 'Миниатюра записи'
    'featured_image' => __( 'Миниатюра записи', 'text_domain' ),
    // Текст для загрузки миниатюры.
    // По умолчанию: 'Задать миниатюру'
    'set_featured_image' => __( 'Задать миниатюру', 'text_domain' ),
    // Текст для удаления миниатюры.
    // По умолчанию: 'Удалить миниатюру'
    'remove_featured_image' => __( 'Удалить миниатюру', 'text_domain' ),
    // По умолчанию: 'Использовать миниатюру'
    'use_featured_image' => __( 'Использовать миниатюру', 'text_domain' ),
    // Текст в пункте меню. По умолчанию: значение аргумента 'name'.
    'menu_name' => __( 'Новости', 'text_domain' ),
    // Текст в админ-баре во вкладке 'Добавить'.
    // По умолчанию: значение аргумента 'singular_name'.
    'name_admin_bar' => __( 'Новость', 'text_domain' ),
    // Текст Screen reader в заголовке в разделе всех записей/страниц.
    // По умолчанию: 'Список записей' или 'Список страниц'
    'items_list' => __( 'Список новостей', 'text_domain' ),
    // Текст Screen reader для постраничной навигации в разделе всех записей/страниц.
    // По умолчанию: 'Постраничная навигация'
    'items_list_navigation' => __( 'Постраничная навигация', 'text_domain' ),
    // Текст Screen reader для фильтра в разделе всех записей/страниц.
    // По умолчанию: 'Фильтр'
    'filter_items_list' => __( 'Фильтр', 'text_domain' ),
    ),
    // Короткое описание записи/страницы. По умолчанию: ''.
    'description' => '',
    // Управление видимостью в админ-панели ('show_in_nav_menus', 'show_ui')
    // и во внешнем фронтэнде ('exclude_from_search', 'publicly_queryable').
    // По умолчанию: false.
    'public' => true,
    // Исключить ли записи из результатов поиска фронтэнда.
    // По умолчанию: значение аргумента 'public'.
    'exclude_from_search' => true,
    // Доступность на внешнем сайте: могут ли запросы быть выполненными во фронтэнде как часть parse_request().
    // По умолчанию: значение аргумента 'public'.
    'publicly_queryable' => true,
    // Возможность управления данным пользовательским типом записи в админ-панели.
    // По умолчанию: значение аргумента 'public'.
    'show_ui' => true,
    // Доступность данного пользовательского типа записи в навигационном меню сайта.
    // По умолчанию: значение аргумента 'public'.
    'show_in_nav_menus' => true,
    // Показывать ли тип записи в админ-меню. Значение аргумента 'show_ui' должно быть true.
    // По умолчанию: значение аргумента 'show_ui'.
    'show_in_menu' => true,
    // Показывать ли тип записи в админ-баре. По умолчанию: значение аргумента 'show_in_menu'.
    'show_in_admin_bar' => true,
   
    // Порядок расположения в админ-меню. Значение аргумента 'show_in_menu' должно быть true.
    // По умолчанию: null - после пункта 'Комментарии'.
    'menu_position' => 5,
    /* Возможные значения:
    5 - после пункта 'Записи';
    10 - после пункта 'Медиафайлы';
    20 - после пункта 'Страницы';
    25 - после пункта 'Комментарии';
    60 - после пункта 'Внешний вид';
    65 - после пункта 'Плагины';
    70 - после пункта 'Пользователи';
    75 - после пункта 'Инструменты';
    80 - после пункта 'Настройки'.
    */

    // URL для загрузки изображения в админ-меню.
    // По умолчанию: null - используется изображение пункта меню 'Записи'.
    // Ссылки на изображения доступны здесь: https://developer.wordpress.org/resource/dashicons/  
    'menu_icon' => 'dashicons-editor-textcolor',

    /* Массив полномочий зарегестрированных пользователей для этого типа записи:
    'capability_type' => 'post',
        'capabilities' => array(
        'edit_post' => 'edit_news',
        'read_post' => 'read_news',
        'delete_post' => 'delete_news',
        'edit_posts' => 'edit_news',
        'edit_others_posts' => 'edit_others_news',
        'publish_posts' => 'publish_news',      
        'read_private_posts' => 'read_private_news',
        'create_posts' => 'edit_news',
    ),
    */

    // Использовать ли внутренние значения по умолчанию для управления правами.
    // По умолчанию: null.
    'map_meta_cap' => null,
    // Является ли тип записи иерархическим (т.е. страницей).
    // Позволяет установливать родительскую страницу. По умолчанию: false.
    'hierarchical' => false,

    // Управление полями для редактирования объекта типа записи.
    // По умолчанию: значения 'title' и 'editor'.
    'supports' => array(
        'title', // Заголовок объекта типа записи.
        'editor', // Редактор контента.
        'author', // Автор.
        'thumbnail', // Миниатюра.
        'excerpt', // Цитата, отрывок.
        'trackbacks', // Отправить обратные ссылки.
        'custom-fields', // Произвольные поля.
        'comments', // Комментарии.
        'revisions', // Сохраняет версии.
        'page-attributes', // Атрибуты.
        'post-formats', // Формат записи.
    ),

    // Обеспечивает обратный вызов функции, которая требуется при настройке метабоксов в разделе редактирования.
    // По умолчанию: null.
    'register_meta_box_cb' => null,
    // Массив связанных таксономий для данного типа записи.
    // Пользовательскую таксономию необходимо зарегестрировать через функцию register_taxonomy().
    // По умолчанию: без таксономий.
    'taxonomies' => array('snews'),
    // Включает архивы данного типа записи.
    // Будет использоваться значение $post_type как ярлык архива по умолчанию. По умолчанию: false
    'has_archive' => false,

    // Возможность перезаписи для данного типа записи.
    // Для предотвращения перезаписи, используют значение false.
    // По умолчанию: true и значение $post_type используется как ярлык.
    'rewrite' => array(
        // Текст в ссылке. По умолчанию: значение $post_type.
        'slug' => 'news',
        // Должна ли структура ссылки быть с базовым URL.
        // Пример: если структура ссылки /blog/,
        // то ссылка при соответствующих параметрах 'with_front'
        // выглядит так: false->/news/, true->/blog/news/
        // По умолчанию: true.
        'with_front' => false,
        // Должна ли структура постоянных ссылок быть встроена для этого типа записи.
        // По умолчанию: значение 'has_archive'.
        'feeds' => false,
        // Должна ли структура ссылок обеспечена быть постраничной навигацией.
        // По умолчанию: true.
        'pages' => true,
    ),
   
    // Перезаписывает конечное значение. По умолчанию: EP_PERMALINK.
    'permalink_epmask' => EP_PERMALINK,
    // Задается значение запроса для данного типа записи.
    //  По умолчанию: true - задается значение $post_type.
    'query_var' => true,
    // Возможность данного типа записи быть экспортированным. По умолчанию: true.
    'can_export' => true,
    // Удалять ли записи данного типа при удалении их автора. По умолчанию: null.
    'delete_with_user' => null,
    // Представлять ли этот тип записи в REST API. По умолчанию: false.
    'show_in_rest' => false,
    // Базовый ярлык данного типа записи когда доступно использование REST API.
    //  По умолчанию: значение $post_type.
    'rest_base' => $post_type,
    // Является ли этот тип записи собственным или встроенным.
    //  Рекомендация: не использовать этот аргумент при регистрации собственного типа сообщения. По умолчанию: false.
    '_builtin' => false,
);
register_post_type( 'news', $args );
}

Создание шаблона для нового типа записей

Создаём в директории шаблона своего сайта на WordPress файл single-news.php. И вставляем туда содержимое файла single.php с теми изменениями, которые вам нужны в дизайне новостей.

Дружелюбные URL в своей таксономии

Если на сайте включены человекопонятные URL (ЧПУ), то для работы новых таксономий WordPress обязательно нужно добавить в файл functions.php следующий php:

// НЕОБХОДИМА для ссылок ЧПУ, иначе страница с категорией будет не найдена
// Удаление slug таксономии:
function taxonomy_link( $link, $term, $taxonomy ) {
    if ( $taxonomy !== 'snews' )
        return $link;
    return str_replace( 'snews/snews/', '', $link );
}
add_filter( 'term_link', 'taxonomy_link', 10, 3 );

// Редирект:
function taxonomy_rewrite_rule() {
    add_rewrite_rule('allnews/?$', 'index.php?snews=allnews', 'top');
}
add_action('init', 'taxonomy_rewrite_rule');

После всех манипуляций с произвольным типом записей в файле functions.php, если у вас ЧПУ ссылки, надо обновить их структуру. Для этого заходим в административной части WordPress по ссылке: «Настройки» > «Постоянные ссылки». И там ничего не меняя, нажимаем кнопку «сохранить изменения».

Если этого не сделать, то новые страницы на сайте с записями новых статей и таксономий этих статей (категорий) не будут найдены.

Вышеприведенный код работает при следующей настройке в постоянных ссылках WordPress:

http://site_name.ru/%post_id%/

Новые записи выглядят следующим образом:

http://site_name.ru/news/novost_odin/

А новые категории показываются так:

http://site_name.ru/snews/rubrika_odin/

Необходимые дополнения для произвольных типов записей

Отдельно читайте как добавить поддержку миниатюр в произвольный тип записей.

Если вам нужно вывести какие-нибудь данные (на подобии is_single), в зависимости от типа произвольных данных, то нужно использовать is_singular:

<?php if ( is_singular( array( 'news', 'article' ) ) ) {?>

<?php } ?>

где news и article — типы произвольных полей.

Если вам пригодилась информация, вы можете поблагодарить автора сайта символическим пожертвованием:

Добавить комментарий

Напишите свой комментарий, если вам есть что добавить/поправить/спросить по теме текущей статьи:
"Создание произвольных типов записей и таксономий"