Custom Post Types в WordPress: регистрация, таксономии и шаблоны

Custom Post Types (CPT) — один из мощнейших инструментов WordPress. С их помощью можно создавать собственные типы контента: портфолио, каталоги, отзывы, вакансии — всё что угодно, со своей структурой и метаданными.

Что такое Custom Post Types

По умолчанию WordPress имеет встроенные типы: post (запись), page (страница), attachment (медиафайл), revision и nav_menu_item. Custom Post Type — это регистрация нового типа с нужными вам параметрами.

Регистрация CPT через register_post_type()


function my_register_portfolio() {
    $labels = [
        'name'               => 'Портфолио',
        'singular_name'      => 'Проект',
        'add_new'            => 'Добавить проект',
        'add_new_item'       => 'Новый проект',
        'edit_item'          => 'Редактировать проект',
        'view_item'          => 'Просмотр проекта',
        'all_items'          => 'Все проекты',
        'search_items'       => 'Поиск проектов',
        'not_found'          => 'Проекты не найдены',
    ];

    $args = [
        'labels'             => $labels,
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'rewrite'            => ['slug' => 'portfolio'],
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => 5,
        'menu_icon'          => 'dashicons-portfolio',
        'supports'           => ['title', 'editor', 'thumbnail', 'excerpt'],
        'show_in_rest'       => true, // включить Gutenberg и REST API
    ];

    register_post_type('portfolio', $args);
}
add_action('init', 'my_register_portfolio');

Код добавляется в functions.php активной темы или в плагин.

Ключевые параметры register_post_type()

Параметр Описание
public Доступен ли тип публично (фронтенд + админка)
has_archive Создать страницу архива (например, /portfolio/)
hierarchical true — как страницы (с родителями), false — как посты
rewrite Настройка ЧПУ-слага
supports Поддерживаемые функции: title, editor, thumbnail, excerpt, comments, author
show_in_rest Подключение к REST API и Gutenberg
menu_icon Иконка в меню админки (dashicons или URL)

Кастомные таксономии для CPT

Таксономии — это системы классификации. Категории и теги — встроенные таксономии. Для портфолио создадим свою — «Технологии»:


function my_register_portfolio_tax() {
    $labels = [
        'name'          => 'Технологии',
        'singular_name' => 'Технология',
        'search_items'  => 'Поиск технологий',
        'all_items'     => 'Все технологии',
        'edit_item'     => 'Редактировать технологию',
        'add_new_item'  => 'Добавить технологию',
    ];

    register_taxonomy('portfolio_tech', ['portfolio'], [
        'labels'            => $labels,
        'hierarchical'      => true,   // как категории
        'show_ui'           => true,
        'show_admin_column' => true,
        'rewrite'           => ['slug' => 'tech'],
        'show_in_rest'      => true,
    ]);
}
add_action('init', 'my_register_portfolio_tax');

Шаблоны для CPT

WordPress ищет шаблоны по иерархии. Для типа portfolio:

  • single-portfolio.php — страница одной записи
  • archive-portfolio.php — страница архива
  • taxonomy-portfolio_tech.php — страница таксономии

Если файла нет, WordPress использует single.php и archive.php соответственно.

Получение записей CPT через WP_Query


$query = new WP_Query([
    'post_type'      => 'portfolio',
    'posts_per_page' => 10,
    'tax_query'      => [
        [
            'taxonomy' => 'portfolio_tech',
            'field'    => 'slug',
            'terms'    => 'php',
        ],
    ],
]);

if ($query->have_posts()) {
    while ($query->have_posts()) {
        $query->the_post();
        echo '<h2><a href="' . get_permalink() . '">' . get_the_title() . '</a></h2>';
    }
    wp_reset_postdata();
}

Добавление метабокса с дополнительными полями


// Регистрируем метабокс
function my_portfolio_meta_box() {
    add_meta_box(
        'portfolio_details',
        'Детали проекта',
        'my_portfolio_meta_box_html',
        'portfolio',
        'normal',
        'high'
    );
}
add_action('add_meta_boxes', 'my_portfolio_meta_box');

// HTML метабокса
function my_portfolio_meta_box_html($post) {
    $url = get_post_meta($post->ID, '_portfolio_url', true);
    wp_nonce_field('portfolio_nonce_action', 'portfolio_nonce');
    echo '';
    echo '';
}

// Сохранение данных
function my_portfolio_save_meta($post_id) {
    if (!isset($_POST['portfolio_nonce'])) return;
    if (!wp_verify_nonce($_POST['portfolio_nonce'], 'portfolio_nonce_action')) return;
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
    if (!current_user_can('edit_post', $post_id)) return;

    if (isset($_POST['portfolio_url'])) {
        update_post_meta($post_id, '_portfolio_url', esc_url_raw($_POST['portfolio_url']));
    }
}
add_action('save_post_portfolio', 'my_portfolio_save_meta');

Сброс Rewrite Rules

После регистрации нового CPT обязательно сбросьте правила permalink. Зайдите в Настройки → Постоянные ссылки и нажмите «Сохранить изменения». Или через WP-CLI:

wp rewrite flush

Custom Post Types делают WordPress настоящей CMS. С их помощью можно строить каталоги, маркетплейсы, базы знаний — практически любые структуры данных без сторонних плагинов.