WordPress изначально работает с двумя основными типами записей — посты и страницы. Однако для реализации более сложных проектов часто требуется создать собственные типы записей (Custom Post Types, CPT), которые помогут структурировать контент и управлять им более эффективно. В этой статье мы подробно разберём, как правильно создавать и настраивать собственные типы записей в WordPress, рассмотрим примеры кода и варианты их использования.
Что такое собственные типы записей (CPT) в WordPress
Собственные типы записей — это дополнительный вид контента, который расширяет стандартный функционал WordPress. CPT позволяют создавать, например, каталоги товаров, портфолио, отзывы, мероприятия и многое другое, отделяя этот контент от обычных записей и страниц. Это повышает удобство управления сайтом и улучшает пользовательский опыт.
Типичные примеры использования CPT:
- Портфолио компании или фрилансера
- Отзывы клиентов
- События и мероприятия
- Каталог продуктов с дополнительными параметрами
Для создания CPT можно использовать плагины, но лучше реализовать их через код, чтобы сохранить лёгкость и гибкость сайта.
Регистрация собственного типа записи: базовый пример
Для регистрации CPT используется функция register_post_type(). Обычно этот код добавляют в файл functions.php темы или в отдельный плагин.
Пример регистрации CPT с именем «Проекты» (projects):
function wpsolution_register_cpt_projects() {
$labels = array(
'name' => 'Проекты',
'singular_name' => 'Проект',
'menu_name' => 'Проекты',
'name_admin_bar' => 'Проект',
'add_new' => 'Добавить новый',
'add_new_item' => 'Добавить новый проект',
'new_item' => 'Новый проект',
'edit_item' => 'Редактировать проект',
'view_item' => 'Просмотреть проект',
'all_items' => 'Все проекты',
'search_items' => 'Поиск проектов',
'not_found' => 'Проекты не найдены',
'not_found_in_trash' => 'В корзине проектов не найдено'
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'rewrite' => array('slug' => 'projects'),
'supports' => array('title', 'editor', 'thumbnail', 'excerpt', 'custom-fields'),
'show_in_rest' => true, // Включает поддержку Gutenberg и REST API
'menu_position' => 5,
'menu_icon' => 'dashicons-portfolio'
);
register_post_type('wpsolution_projects', $args);
}
add_action('init', 'wpsolution_register_cpt_projects');В этом примере мы создаём CPT с названием wpsolution_projects (рекомендуется префикс для избежания конфликтов), задаём читаемые ярлыки, включаем поддержку редактора, миниатюр и метаполей, а также REST API для интеграций.
Настройка таксономий для собственных типов записей
Очень часто нужно не только создать CPT, но и добавить к нему собственные рубрики (таксономии), отличные от стандартных категорий или меток. Например, для проектов это может быть «Тип проекта» или «Технологии».
Пример регистрации таксономии «Тип проекта» для CPT «Проекты»:
function wpsolution_register_taxonomy_project_type() {
$labels = array(
'name' => 'Типы проектов',
'singular_name' => 'Тип проекта',
'search_items' => 'Поиск типов проектов',
'all_items' => 'Все типы проектов',
'edit_item' => 'Редактировать тип проекта',
'update_item' => 'Обновить тип проекта',
'add_new_item' => 'Добавить новый тип проекта',
'new_item_name' => 'Название нового типа проекта',
'menu_name' => 'Типы проектов',
);
$args = array(
'hierarchical' => true, // как категории
'labels' => $labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array('slug' => 'project-type'),
'show_in_rest' => true
);
register_taxonomy('wpsolution_project_type', 'wpsolution_projects', $args);
}
add_action('init', 'wpsolution_register_taxonomy_project_type');Теперь при создании или редактировании проекта можно будет выбрать один или несколько типов проекта, которые можно вывести на фронтенде для фильтрации или отображения.
Вывод собственных типов записей на сайте
Чтобы вывести записи собственного типа на сайте, можно использовать WP_Query с параметром post_type. Например, вывести последние 5 проектов:
$args = array(
'post_type' => 'wpsolution_projects',
'posts_per_page' => 5,
'orderby' => 'date',
'order' => 'DESC'
);
$projects_query = new WP_Query($args);
if ($projects_query->have_posts()) {
echo '<ul>';
while ($projects_query->have_posts()) {
$projects_query->the_post();
echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
}
echo '</ul>';
wp_reset_postdata();
} else {
echo 'Проекты не найдены.';
}Этот код можно разместить в шаблоне темы, виджете или плагине для вывода списка проектов.
Дополнительные возможности и советы по CPT
1. Поддержка метаполей и кастомных полей. Для расширения данных CPT используйте Metabox или Advanced Custom Fields (ACF). Например, для проектов можно добавить дату начала, статус, ссылку на демо и т.д.
2. Использование REST API. Включение 'show_in_rest' => true в аргументах регистрации CPT позволяет работать с контентом через REST API, что удобно для SPA или мобильных приложений.
3. SEO-оптимизация. Для CPT можно подключать SEO-плагины, например, Yoast SEO или Clearfy Pro, которые распознают собственные типы записей и позволяют оптимизировать их вывод.
4. Права доступа и роли. При необходимости можно ограничить доступ к CPT для определённых ролей пользователей через capability_type и map_meta_cap в аргументах.
5. Использование плагинов для удобства. Если хочется быстро создать CPT без кода, можно использовать плагин Clearfy Pro с модулем управления CPT, но кодовый подход даёт больше контроля.
Пример комплексного решения: CPT с таксономией и метаполями
Допустим, вы создаёте сайт с каталогом курсов. Создадим CPT «Курсы» и таксономию «Категории курсов», а также добавим метаполе «Стоимость».
Регистрация CPT и таксономии:
function wpsolution_register_cpt_courses() {
register_post_type('wpsolution_courses', array(
'labels' => array(
'name' => 'Курсы',
'singular_name' => 'Курс'
),
'public' => true,
'has_archive' => true,
'supports' => array('title', 'editor', 'thumbnail'),
'show_in_rest' => true
));
register_taxonomy('wpsolution_course_category', 'wpsolution_courses', array(
'labels' => array('name' => 'Категории курсов'),
'hierarchical' => true,
'show_in_rest' => true
));
}
add_action('init', 'wpsolution_register_cpt_courses');Добавление метаполя «Стоимость» через Metabox:
function wpsolution_add_course_meta_box() {
add_meta_box('wpsolution_course_price', 'Стоимость курса', 'wpsolution_course_price_callback', 'wpsolution_courses', 'side');
}
add_action('add_meta_boxes', 'wpsolution_add_course_meta_box');
function wpsolution_course_price_callback($post) {
wp_nonce_field('wpsolution_save_course_price', 'wpsolution_course_price_nonce');
$value = get_post_meta($post->ID, '_wpsolution_course_price', true);
echo '<label for="wpsolution_course_price_field">Цена (в рублях):</label>';
echo '<input type="number" id="wpsolution_course_price_field" name="wpsolution_course_price_field" value="' . esc_attr($value) . '" style="width:100%" />';
}
function wpsolution_save_course_price($post_id) {
if (!isset($_POST['wpsolution_course_price_nonce']) || !wp_verify_nonce($_POST['wpsolution_course_price_nonce'], 'wpsolution_save_course_price')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (isset($_POST['wpsolution_course_price_field'])) {
update_post_meta($post_id, '_wpsolution_course_price', sanitize_text_field($_POST['wpsolution_course_price_field']));
}
}
add_action('save_post', 'wpsolution_save_course_price');Такой подход позволяет полностью контролировать структуру и данные курсов, а также легко выводить их на сайте.
Вывод метаполей и таксономий в шаблонах
Чтобы вывести цену курса и его категории в шаблоне single-wpsolution_courses.php, используйте следующий код:
if (have_posts()) {
while (have_posts()) {
the_post();
echo '<h1>' . get_the_title() . '</h1>';
the_content();
$price = get_post_meta(get_the_ID(), '_wpsolution_course_price', true);
if ($price) {
echo '<p><strong>Стоимость:</strong> ' . esc_html($price) . ' ₽</p>';
}
$terms = get_the_terms(get_the_ID(), 'wpsolution_course_category');
if ($terms && !is_wp_error($terms)) {
$categories = wp_list_pluck($terms, 'name');
echo '<p><strong>Категории:</strong> ' . implode(', ', $categories) . '</p>';
}
}
}Таким образом, вы получаете полностью кастомизированный тип записей с расширенной информацией.