В WordPress стандартно используется тип записей 'post' для блоговых записей и 'page' для страниц. Однако при разработке сайтов часто возникает необходимость создать собственные типы записей (Custom Post Types, CPT), которые позволят организовать данные более структурированно и удобно. В этой статье мы подробно разберём, как правильно создать и зарегистрировать собственный тип записей, а также как расширить его функциональность, чтобы решить конкретные задачи.
Зачем использовать собственные типы записей в WordPress
Использование CPT позволяет отделить разные по смыслу данные на сайте. Например, если вы создаёте сайт для кинотеатра, можно создать отдельный тип записей «фильмы», который будет хранить информацию о фильмах, включая жанр, дату выхода, рейтинг и так далее. Это гораздо удобнее и логичнее, чем пытаться хранить все данные в обычных записях или страницах.
Кроме того, CPT легко интегрируются с таксономиями, метаполями, шаблонами вывода и REST API, что даёт гибкие возможности для разработки и масштабирования сайта.
Рассмотрим создание CPT на конкретном примере — создадим тип записей 'wpdeveloper_project' для хранения проектов разработчика.
Регистрация собственного типа записей WordPress: пошаговое руководство
Для регистрации CPT используется функция register_post_type(). Обычно её вызывают в хуке init. Вот базовый пример:
function wpdeveloper_register_cpt_project() {
$labels = array(
'name' => 'Проекты',
'singular_name' => 'Проект',
'menu_name' => 'Проекты',
'name_admin_bar' => 'Проект',
'add_new' => 'Добавить новый',
'add_new_item' => 'Добавить новый проект',
'edit_item' => 'Редактировать проект',
'new_item' => 'Новый проект',
'view_item' => 'Просмотреть проект',
'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' => 'project' ),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => 5,
'menu_icon' => 'dashicons-portfolio',
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields' ),
'show_in_rest' => true // чтобы CPT был доступен в Gutenberg и REST API
);
register_post_type( 'wpdeveloper_project', $args );
}
add_action( 'init', 'wpdeveloper_register_cpt_project' );
В этом примере мы создаём тип записей с названием 'wpdeveloper_project', который будет отображаться в админке под меню 'Проекты'. Поддерживаются стандартные поля: заголовок, редактор, миниатюра и пользовательские поля.
Объяснение параметров register_post_type
- labels — массив с названиями для интерфейса.
- public — тип записей виден на фронтенде.
- rewrite — настройки для URL.
- supports — какие стандартные метаполя поддерживаются.
- show_in_rest — включение поддержки REST API и редактора Gutenberg.
Добавление пользовательских метаполей для кастомного типа записей
Обычно для CPT нужны дополнительные поля. Например, для проекта — ссылка на репозиторий, статус, дата начала и так далее. Для этого можно использовать метаполя (Custom Fields). Самый простой способ — добавить метабоксы вручную с помощью хуков.
function wpdeveloper_add_meta_boxes_project() {
add_meta_box(
'wpdeveloper_project_details',
'Детали проекта',
'wpdeveloper_project_meta_box_callback',
'wpdeveloper_project',
'normal',
'default'
);
}
add_action( 'add_meta_boxes', 'wpdeveloper_add_meta_boxes_project' );
function wpdeveloper_project_meta_box_callback( $post ) {
wp_nonce_field( 'wpdeveloper_save_project_meta', 'wpdeveloper_project_meta_nonce' );
$repo_url = get_post_meta( $post->ID, '_wpdeveloper_repo_url', true );
$status = get_post_meta( $post->ID, '_wpdeveloper_status', true );
echo '<p><label for="wpdeveloper_repo_url">URL репозитория:</label></p>';
echo '<input type="text" id="wpdeveloper_repo_url" name="wpdeveloper_repo_url" value="' . esc_attr( $repo_url ) . '" size="30" />';
echo '<p><label for="wpdeveloper_status">Статус проекта:</label></p>';
echo '<select id="wpdeveloper_status" name="wpdeveloper_status">';
$options = array('В разработке', 'Завершён', 'Приостановлен');
foreach ( $options as $option ) {
$selected = selected( $status, $option, false );
echo "<option value=\"$option\" $selected>$option</option>";
}
echo '</select>';
}
function wpdeveloper_save_project_meta( $post_id ) {
if ( ! isset( $_POST['wpdeveloper_project_meta_nonce'] ) ) {
return;
}
if ( ! wp_verify_nonce( $_POST['wpdeveloper_project_meta_nonce'], 'wpdeveloper_save_project_meta' ) ) {
return;
}
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
if ( isset( $_POST['wpdeveloper_repo_url'] ) ) {
update_post_meta( $post_id, '_wpdeveloper_repo_url', sanitize_text_field( $_POST['wpdeveloper_repo_url'] ) );
}
if ( isset( $_POST['wpdeveloper_status'] ) ) {
update_post_meta( $post_id, '_wpdeveloper_status', sanitize_text_field( $_POST['wpdeveloper_status'] ) );
}
}
add_action( 'save_post', 'wpdeveloper_save_project_meta' );
В результате в админке в карточке проекта появится метабокс с дополнительными полями, значения которых сохраняются и доступны для вывода на сайте.
Вывод данных кастомного типа записей на сайте — примеры шаблонов
После регистрации CPT и добавления метаполей нужно вывести информацию на сайте. Для этого можно создать файл шаблона single-wpdeveloper_project.php в вашей теме.
<?php get_header(); ?>
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
$repo_url = get_post_meta( get_the_ID(), '_wpdeveloper_repo_url', true );
$status = get_post_meta( get_the_ID(), '_wpdeveloper_status', true );
?>
<h1><?php the_title(); ?></h1>
<div><?php the_content(); ?></div>
<p><strong>Статус проекта:</strong> <?php echo esc_html( $status ); ?></p>
<p><strong>Репозиторий:</strong> <a href="<?php echo esc_url( $repo_url ); ?>" target="_blank"><?php echo esc_html( $repo_url ); ?></a></p>
<?php
endwhile;
endif;
?>
<?php get_footer(); ?>
Такой подход даёт полный контроль над представлением данных и позволяет легко кастомизировать вывод.
Рекомендации по SEO и производительности для кастомных типов записей
Для улучшения SEO рекомендуется настроить правильные ЧПУ (человеко-понятные урлы) через параметр rewrite и обеспечить наличие уникальных метатегов. Для этого можно использовать плагины типа Clearfy Pro с ссылкой на Clearfy Pro, который помогает оптимизировать SEO и убрать лишние запросы.
Для повышения производительности стоит избегать чрезмерного использования метаполей и кешировать запросы к CPT. Используйте WP_Query с правильными параметрами и индексируйте метаполя, если они активно используются в фильтрах.
Использование REST API с кастомными типами записей WordPress
Параметр show_in_rest позволяет работать с CPT через REST API. Это удобно для создания SPA-приложений и взаимодействия с внешними сервисами.
Пример получения всех проектов через REST API:
GET /wp-json/wp/v2/wpdeveloper_project
Если нужно добавить кастомные поля в REST API, можно использовать фильтр rest_prepare_{post_type}:
function wpdeveloper_add_custom_fields_to_rest( $response, $post, $request ) {
$response->data['repo_url'] = get_post_meta( $post->ID, '_wpdeveloper_repo_url', true );
$response->data['status'] = get_post_meta( $post->ID, '_wpdeveloper_status', true );
return $response;
}
add_filter( 'rest_prepare_wpdeveloper_project', 'wpdeveloper_add_custom_fields_to_rest', 10, 3 );
Это позволит клиентским приложениям получать все необходимые данные через API.
Заключение
Создание собственных типов записей в WordPress — мощный инструмент для структурирования нестандартных данных. Важно грамотно регистрировать CPT, добавлять метаполя и продумывать вывод информации. Такой подход значительно упрощает поддержку и развитие сайта. Если хотите ускорить разработку и оптимизацию, рекомендуем ознакомиться с плагинами Clearfy Pro и темами Reboot для улучшения производительности и внешнего вида.