WordPress по умолчанию предлагает несколько типов записей: посты, страницы, вложения. Однако для многих проектов этого недостаточно, и возникает необходимость создавать собственные типы записей — Custom Post Types (CPT). В этой статье мы подробно разберем, как правильно создать и зарегистрировать собственный тип записи в WordPress с помощью функций, оформленных под префиксом WPAll, чтобы избежать конфликтов и упростить поддержку.
Что такое Custom Post Type и зачем он нужен
Custom Post Type — это дополнительный тип контента, который расширяет возможности сайта. Например, если вы создаете сайт с каталогом товаров, событиями, отзывами или портфолио, лучше выделить их в отдельный тип записи, чтобы удобно организовать админку, фильтрацию и вывод на фронтенде.
Преимущества использования CPT:
- Разделение контента по смыслу и структуре
- Настройка отдельных метаданных и таксономий
- Удобство управления в админке
- Гибкость вывода на сайте
Создание CPT — стандартная практика для профессиональной разработки на WordPress.
Регистрация собственного типа записи с помощью функции WPAll_register_custom_post_type
Для удобства и стандартизации создадим функцию wpall_register_custom_post_type, которая будет регистрировать Custom Post Type. Ниже пример кода, который нужно добавить в файл functions.php вашей темы или в отдельный плагин.
function wpall_register_custom_post_type() {
$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,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array('slug' => 'portfolio'),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => 5,
'menu_icon' => 'dashicons-portfolio',
'supports' => array('title', 'editor', 'thumbnail', 'excerpt', 'comments'),
);
register_post_type('wpall_portfolio', $args);
}
add_action('init', 'wpall_register_custom_post_type');Этот код создаст новый тип записи с названием «Портфолио» и ярлыком в меню админки. Обратите внимание, что в названии типа записи используется префикс wpall_ — это хорошая практика, чтобы избежать конфликтов с плагинами и темами.
Разбор параметров функции register_post_type
Параметры в массиве $args позволяют настроить поведение CPT:
- public — видимость типа записи на сайте и в админке;
- show_ui — показывать ли интерфейс для управления в админке;
- rewrite — настройки URL (чпу);
- supports — какие стандартные функции редактора использовать (заголовок, редактор, миниатюра, комментарии и т.д.);
- menu_icon — иконка в меню админки.
Добавление кастомных таксономий для собственного типа записи
Часто для CPT нужно создавать собственные категории и метки. Для этого регистрируем таксономии.
function wpall_register_custom_taxonomies() {
// Категории для портфолио
$labels_cat = array(
'name' => 'Категории портфолио',
'singular_name' => 'Категория портфолио',
'search_items' => 'Поиск категорий',
'all_items' => 'Все категории',
'edit_item' => 'Редактировать категорию',
'update_item' => 'Обновить категорию',
'add_new_item' => 'Добавить новую категорию',
'new_item_name' => 'Новое имя категории',
'menu_name' => 'Категории портфолио',
);
$args_cat = array(
'hierarchical' => true,
'labels' => $labels_cat,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array('slug' => 'portfolio-category'),
);
register_taxonomy('wpall_portfolio_category', array('wpall_portfolio'), $args_cat);
}
add_action('init', 'wpall_register_custom_taxonomies');В этом примере мы создаем иерархическую таксономию «Категории портфолио», которая работает как стандартные категории для постов. Аналогично можно создать метки, изменив параметр hierarchical на false.
Вывод Custom Post Type на сайте: пример WPAll_get_portfolio_list
Чтобы вывести список записей CPT на странице, создадим функцию wpall_get_portfolio_list, которая возвращает HTML с перечнем проектов.
function wpall_get_portfolio_list($count = 10) {
$args = array(
'post_type' => 'wpall_portfolio',
'posts_per_page' => $count,
'post_status' => 'publish',
);
$query = new WP_Query($args);
if (!$query->have_posts()) {
return '<p>Проекты не найдены.</p>';
}
$output = '<ul class="wpall-portfolio-list">';
while ($query->have_posts()) {
$query->the_post();
$output .= '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
}
wp_reset_postdata();
$output .= '</ul>';
return $output;
}Для вывода списка на любой странице или в шаблоне просто вызовите:
echo wpall_get_portfolio_list(5); // Показать 5 проектовДобавление шорткода для вывода портфолио
Чтобы контент-менеджеры могли выводить список портфолио через админку, регистрируем шорткод:
function wpall_portfolio_shortcode($atts) {
$atts = shortcode_atts(array('count' => 5), $atts, 'wpall_portfolio');
return wpall_get_portfolio_list(intval($atts['count']));
}
add_shortcode('wpall_portfolio', 'wpall_portfolio_shortcode');Теперь в любой записи или странице можно вставить [wpall_portfolio count="3"] для вывода 3 проектов.
Как расширять функциональность CPT: метаполя и кастомные шаблоны
Для добавления дополнительных данных к проектам, например, ссылок, дат, описаний, используйте метабоксы и метаполя. Для этого можно применить плагины Advanced Custom Fields (ACF) или регистрировать метаполя вручную через функции WordPress.
Пример простого метабокса с полем URL:
function wpall_add_portfolio_metabox() {
add_meta_box('wpall_portfolio_link', 'Ссылка на проект', 'wpall_portfolio_link_callback', 'wpall_portfolio', 'normal', 'high');
}
add_action('add_meta_boxes', 'wpall_add_portfolio_metabox');
function wpall_portfolio_link_callback($post) {
$value = get_post_meta($post->ID, '_wpall_portfolio_link', true);
echo '<label for="wpall_portfolio_link_field">URL проекта:</label> ';
echo '<input type="url" id="wpall_portfolio_link_field" name="wpall_portfolio_link_field" value="' . esc_attr($value) . '" size="25" />';
}
function wpall_save_portfolio_metabox($post_id) {
if (array_key_exists('wpall_portfolio_link_field', $_POST)) {
update_post_meta($post_id, '_wpall_portfolio_link', sanitize_text_field($_POST['wpall_portfolio_link_field']));
}
}
add_action('save_post', 'wpall_save_portfolio_metabox');Для вывода этого поля в шаблоне используйте:
$project_link = get_post_meta(get_the_ID(), '_wpall_portfolio_link', true);
if ($project_link) {
echo '<p><a href="' . esc_url($project_link) . '" target="_blank">Посмотреть проект</a></p>';
}Для кастомизации внешнего вида CPT создайте шаблон single-wpall_portfolio.php в папке темы. В нем можно оформить вывод произвольно, используя стандартные функции WordPress.
Полезные плагины для работы с Custom Post Type
Хотя мы рассмотрели ручное создание CPT, плагины могут значительно упростить процесс:
- Custom Post Type UI — удобный интерфейс для создания типов записей и таксономий без кода;
- Advanced Custom Fields (ACF) — для добавления и управления метаполями;
- Toolset Types — комплексный набор для создания и настройки CPT, таксономий и полей;
- Pods — альтернативное решение для создания CPT и кастомных полей.
Используйте плагины, если хотите ускорить разработку или не хотите писать код вручную.
Советы по отладке и поддержке Custom Post Types
При создании собственных типов записей важно помнить несколько моментов:
- Всегда используйте уникальные префиксы в названиях функций и идентификаторов (например,
wpall_), чтобы избежать конфликтов; - После регистрации CPT обязательно сбрасывайте правила перезаписи ссылок, перейдя в админке в Настройки > Постоянные ссылки и нажав кнопку «Сохранить» без изменений;
- Тестируйте вывод и работу CPT на разных уровнях доступа и с разными ролями пользователей;
- Документируйте код, чтобы облегчить поддержку и доработки;
- Используйте дочерние темы или плагины для кастомного кода, чтобы не потерять изменения при обновлении.