Шаблон таксономии в WordPress: как вывести архив терминов

Шаблон таксономии в WordPress: как вывести архив терминов

Кратко: Архив таксономии — это страница, на которой WordPress показывает все записи, привязанные к одному термину: рубрике, метке или своему значению вместе с кастомным типом записей. Если посетитель открывает ссылку вида /category/novosti/ или /genre/fantasy/, он попадает именно на архив термина. Шаблон для такой страницы WordPress подбирает сам по иерархии файлов: сначала taxonomy-{таксономия}-{термин}.php, затем taxonomy-{таксономия}.php, потом taxonomy.php, archive.php и в самом конце index.php. Чтобы сделать свой вывод архива терминов, достаточно добавить в тему один файл-шаблон и вывести в нём записи обычным циклом или через WP_Query. Ниже — готовые примеры кода: создание шаблона, вывод записей термина и пагинация, список терминов через get_terms(), описание термина через term_description(), метаполя термина и настройка красивых ссылок (ЧПУ) для своих таксономий.

Что такое архив таксономии и как WordPress выбирает для него шаблон

Таксономия в WordPress — это механизм группировки записей. У стандартных записей есть две встроенные таксономии: рубрики (category) и метки (post_tag). Для собственных типов записей, например «Портфолио» или «Товары», таксономии обычно создают отдельно — об этом подробно в статье про кастомные типы записей и свои таксономии.

Внутри таксономии хранятся термины (terms) — конкретные значения. Для таксономии «Жанр» терминами будут «Фэнтези», «Детектив», «Роман». Когда посетитель открывает страницу термина, WordPress собирает все записи, которые к нему привязаны, и показывает их списком. Эта страница называется архивом таксономии, и по своей природе она ничем не отличается от архива рубрики или архива метки: тот же список записей, та же пагинация, та же сортировка.

Ключевой момент, который нужно понять новичку: отдельная страница для архива термина не создаётся вручную через редактор. WordPress формирует её на лету, когда встречает подходящий адрес в запросе. Ваша задача — лишь описать, как эта страница выглядит, положив нужный файл-шаблон в папку темы.

Чтобы понять, какой шаблон подключился, удобно пользоваться условными тегами. Внутри архива таксономии срабатывает проверка is_tax(), для рубрик — is_category(), для меток — is_tag(), а общий признак архива даёт is_archive(). Проверить конкретную таксономию можно так: is_tax( 'genre' ), а конкретный термин — is_tax( 'genre', 'fantasy' ). Эти проверки пригодятся и для условной загрузки стилей, и для отдельных блоков вывода.

Полезно помнить, что WordPress сначала ищет шаблон в дочерней теме, а потом уже в родительской. Поэтому все правки удобно держать в дочерней теме — родительская останется нетронутой и спокойно обновится.

Иерархия шаблонов таксономии: какой файл за что отвечает

У WordPress есть строгий порядок поиска шаблона. Он называется иерархией шаблонов, и для архивов таксономий выглядит так — от самого точного совпадения к самому общему:

  • taxonomy-{таксономия}-{термин}.php — самый точный файл. Например, taxonomy-genre-fantasy.php сработает только для термина «fantasy» таксономии «genre». Нужен, когда для одного-двух терминов требуется особый дизайн.
  • taxonomy-{таксономия}.php — основной рабочий файл. Например, taxonomy-genre.php обслуживает все термины таксономии «genre». Это то, что вы будете создавать чаще всего.
  • taxonomy.php — общий шаблон для всех таксономий, у которых нет своего файла. Удобен для маленьких сайтов: один файл на все архивы.
  • archive.php — общий шаблон всех архивов: рубрик, меток, дат, авторов. Если за него отвечает ваша тема, свой файл можно не создавать вовсе.
  • index.php — последний рубеж. Если ничего другого не найдено, WordPress выведет архив через него в упрощённом виде.

Порядок именно такой: чем точнее имя файла описывает таксономию и термин, тем выше его приоритет. Если существует одновременно taxonomy-genre-fantasy.php и taxonomy-genre.php, для термина «fantasy» подключится первый, а второй — для остальных терминов.

Отдельно стоит запомнить, что для встроенных рубрик и меток WordPress ищет свои файлы: category.php, category-{slug}.php, tag.php, tag-{slug}.php. Файл taxonomy-category.php для рубрик не сработает — это частая ошибка новичков, которые путают таксономию по имени и её «встроенное» имя шаблона.

Проверить, какой файл реально подключился, можно с помощью отладочного вывода: в конце functions.php временно добавьте фильтр template_include, который выведет имя выбранного шаблона. Ещё проще — установить плагин вроде Query Monitor, но для разовых проверок маленькой функции достаточно.

Как создать шаблон архива терминов: первый рабочий пример

Начнём с самого частого случая: своя таксономия genre, привязанная к типу записей book. Нужно, чтобы архивы всех жанров выводились по нашему дизайну. Создаём в дочерней теме файл taxonomy-genre.php — имя файла должно точно повторять машинное имя таксономии, которое вы указали при её регистрации в register_taxonomy().

Базовый шаблон получится таким:

<?php
/**
 * Шаблон архива терминов таксономии «genre».
 */
get_header(); ?>

<main class="site-main">
    <header class="archive-header">
        <?php
        // Заголовок термина, например «Жанр: Фэнтези».
        single_term_title( '<h1 class="archive-title">', '</h1>' );
        ?>
        <?php
        // Описание термина из админки, если оно заполнено.
        if ( $description = term_description() ) {
            echo '<div class="archive-desc">' . $description . '</div>';
        }
        ?>
    </header>

    <?php if ( have_posts() ) : ?>
        <div class="posts-grid">
            <?php while ( have_posts() ) : the_post(); ?>
                <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                    <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
                    <div class="entry-excerpt"><?php the_excerpt(); ?></div>
                </article>
            <?php endwhile; ?>
        </div>

        <?php
        // Постраничная навигация по архиву.
        the_posts_pagination( array(
            'mid_size'  => 2,
            'prev_text' => 'Назад',
            'next_text' => 'Вперёд',
        ) );
        ?>
    <?php else : ?>
        <p>В этом жанре пока нет записей.</p>
    <?php endif; ?>
</main>

<?php get_sidebar(); get_footer();

Разберём ключевые элементы. Функция get_header() и get_footer() подключают шапку и подвал темы, поэтому свой HTML-каркас писать не нужно. Функция single_term_title() сама подставляет название текущего термина — не нужно вручную узнавать, какой именно жанр открыт. А term_description() возвращает описание термина из админки, что полезно и для посетителей, и для SEO: уникальный текст на архиве помогает ранжированию.

Цикл have_posts() — the_post() — базовый инструмент вывода записей. Он работает и в архивах таксономий: WordPress уже подготовил выборку нужных записей, вам остаётся только её отобразить. Именно поэтому для стандартного архива не требуется писать собственный запрос.

Если вы редактируете родительскую тему напрямую, помните о риске: при обновлении темы файл будет перезаписан. Правильнее держать шаблон в дочерней теме — как это устроено, пошагово разобрано в гайде про дочернюю тему WordPress. А если нужен особый шаблон не для архива, а для обычной страницы, пригодится материал про кастомные шаблоны страниц.

Вывод записей термина: основной цикл, WP_Query и пагинация

Стандартного цикла хватает почти всегда. Но иногда нужно вывести записи термина не целиком, а с фильтрами: только последние пять, только определённого типа, в другом порядке. Тогда на помощь приходит WP_Query с параметром tax_query.

<?php
// Получаем текущий термин архива.
$term = get_queried_object();

$query = new WP_Query( array(
    'post_type'      => 'book',
    'posts_per_page' => 6,
    'orderby'        => 'date',
    'order'          => 'DESC',
    'tax_query'      => array(
        array(
            'taxonomy' => 'genre',
            'field'    => 'term_id',
            'terms'    => $term->term_id,
        ),
    ),
) );

if ( $query->have_posts() ) {
    while ( $query->have_posts() ) {
        $query->the_post();
        the_title( '<h3>', '</h3>' );
    }
    wp_reset_postdata();
}

Параметр tax_query — это массив условий по таксономиям. Ключевые поля: taxonomy (машинное имя), field (по какому признаку искать: term_id, slug или name) и terms (значение или массив значений). Если нужно исключить термин, в tax_query добавляют оператор 'operator' => 'NOT IN'. Более сложные условия и вложенные группы запросов разобраны в отдельной статье про WP_Query и работу с запросами.

Важная деталь: после кастомного WP_Query всегда вызывайте wp_reset_postdata(). Он возвращает глобальную переменную $post к исходной записи, иначе последующие функции вроде the_title() начнут выводить данные последней записи из вашего запроса. Это одна из самых частых «загадочных» ошибок на архивах.

Что касается пагинации, у новичков она почти всегда связана с одним и тем же провалом: на второй странице архива показываются те же записи, что и на первой. Причина — в кастомном запросе не передан номер текущей страницы. Лечится это параметром paged:

<?php
$paged = max( 1, get_query_var( 'paged' ), get_query_var( 'page' ) );

$query = new WP_Query( array(
    'post_type'      => 'book',
    'posts_per_page' => 6,
    'paged'          => $paged,
) );

// ... вывод записей ...

// Навигация с учётом кастомного запроса.
echo paginate_links( array(
    'total'   => $query->max_num_pages,
    'current' => $paged,
    'base'    => str_replace( 999999999, '%#%', get_pagenum_link( 999999999 ) ),
) );

Функция get_query_var( 'paged' ) возвращает номер текущей страницы пагинации, а max_num_pages — общее число страниц в запросе. Без параметра paged WordPress думает, что вы всегда на первой странице. И ещё: если архив тормозит на большом числе записей, стоит проверить, не тянет ли шаблон лишние ресурсы на каждой странице — об этом в материале про кэширование WordPress для новичков.

Как вывести список терминов таксономии: get_terms и ссылки на архивы

Часто на странице нужно показать не записи, а сами термины: облако рубрик, перечень жанров, навигацию по категориям товаров. Для этого есть функция get_terms() — она возвращает массив терминов таксономии.

<?php
$terms = get_terms( array(
    'taxonomy'   => 'genre',
    'hide_empty' => true,   // не показывать термины без записей.
    'orderby'    => 'name',
    'order'      => 'ASC',
) );

if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
    echo '<ul class="genre-list">';
    foreach ( $terms as $term ) {
        printf(
            '<li><a href="%s">%s <span>(%d)</span></a></li>',
            esc_url( get_term_link( $term ) ),
            esc_html( $term->name ),
            (int) $term->count
        );
    }
    echo '</ul>';
}

Обратите внимание на два момента. Первый: функция всегда может вернуть объект WP_Error, поэтому проверяйте результат через is_wp_error() — иначе на несуществующей таксономии получите ошибку PHP. Второй: ссылку на архив термина даёт get_term_link( $term ), и её обязательно прогонять через esc_url(), а название — через esc_html(). Такое экранирование защищает вывод от XSS.

Параметр hide_empty стоит держать в значении true: пустые термины ведут на архив без записей — это плохо и для посетителя, и для поисковой выдачи. А число записей в свойстве count удобно для счётчика рядом с названием.

Для выпадающего списка терминов, который сразу переводит на нужный архив, достаточно небольшого скрипта на JavaScript. Данные удобно передать из PHP через wp_localize_script():

// JS: переход на архив выбранного термина.
document.getElementById( 'genre-select' ).addEventListener( 'change', function () {
    var url = this.value;
    if ( url ) {
        window.location.href = url;
    }
} );

Такой приём хорош для мобильной версии, где длинный список ссылок занимает слишком много места. Подобные элементы навигации обычно выводят в сайдбаре или в виджете — базовые правила есть в статье про виджеты и сайдбары WordPress и в гайде про меню и навигацию WordPress.

Описание термина, заголовок и картинка: term meta и get_term_meta

Термины таксономии устроены беднее записей: у них есть название, ярлык (slug), описание и родитель. Но этого часто мало — хочется добавить к рубрике картинку, SEO-текст или значок. Начиная с WordPress 4.4 у терминов появились метаполя, и работать с ними можно через те же функции, что и у записей.

<?php
// Вывести миниатюру термина, сохранённую в метаполе term_image.
$term = get_queried_object();
$image_id = get_term_meta( $term->term_id, 'term_image_id', true );

if ( $image_id ) {
    echo wp_get_attachment_image( $image_id, 'medium', false, array( 'class' => 'term-thumb' ) );
}

// Заголовок и описание термина.
single_term_title( '<h1>', '</h1>' );
echo wp_kses_post( term_description() );

Функция get_term_meta() принимает ID термина, имя ключа и третий параметр true — он означает «верни одиночное значение», а не массив. Записывают метаполя через update_term_meta(), а удаляют — delete_term_meta(). Если вы уже пользуетесь плагином ACF, поля термина создаются прямо в его интерфейсе, а вывод почти не отличается от обычных метаполей — подробнее в гайде про ACF поля в WordPress.

Есть и готовый приём для картинки без ACF: в собственном коде добавьте к таксономии форму загрузки изображения и сохраняйте ID вложения в term_image_id. Но для новичка на порядок быстрее поставить ACF или тематический плагин — это экономит вечер времени.

Не забывайте про term_description(): если специально заполнить описание у каждого термина, архивы получат уникальный текст. Это заметно улучшает поведенческие факторы и помогает страницам ранжироваться. Для более тонкой SEO-настройки заголовков и описаний удобен отдельный разбор про настройку Rank Math и Yoast.

Красивые ссылки: rewrite slug таксономии и настройка ЧПУ

Адрес архива зависит от того, как вы зарегистрировали таксономию. Параметр rewrite задаёт «человекопонятную» часть ссылки. Пример регистрации с аккуратным слагом:

<?php
register_taxonomy( 'genre', array( 'book' ), array(
    'label'        => 'Жанры',
    'public'       => true,
    'hierarchical' => true,
    'show_in_rest' => true, // поддержка блочного редактора и REST API.
    'rewrite'      => array(
        'slug'         => 'zhanny',   // адрес: /zhanny/fantasy/
        'with_front'   => false,      // не добавлять префикс блога.
        'hierarchical' => true,       // вложенные ссылки для подтерминов.
    ),
) );

После изменения слага иерархию ссылок обязательно нужно пересобрать. Самый простой способ — зайти в админке в «Настройки → Постоянные ссылки» и нажать «Сохранить». Под капотом это вызывает flush_rewrite_rules(), и новые адреса начинают работать. Вызывать сброс в коде на каждом запросе нельзя — это ресурсоёмкая операция, допустимая разве что на хуке активации плагина.

Обратите внимание на параметр show_in_rest => true. С ним таксономия становится доступна в блочном редакторе и через REST API — например, для фильтрации записей на JavaScript без перезагрузки страницы. Если планируете выводить термины в фильтрах каталога, лучше сразу включить эту опцию. А про то, что такое REST API простыми словами, есть отдельный материал — REST API WordPress.

Если же архив термина отдаёт 404 или ссылка выглядит как ?taxonomy=genre&term=fantasy, причина обычно в одном из двух: не сохранены постоянные ссылки после смены слага, либо таксономия зарегистрирована с public => false. Проверить, что ещё может поломать адреса, поможет разбор про настройку ЧПУ и permalinks в WordPress.

Таблица: иерархия шаблонов для архивов и терминов

Сведём файлы шаблонов в одну таблицу, чтобы держать под рукой порядок их приоритета.

Файл шаблона Для чего подходит Приоритет Условный тег
taxonomy-genre-fantasy.php Один конкретный термин конкретной таксономии 1 — наивысший is_tax( 'genre', 'fantasy' )
taxonomy-genre.php Все термины таксономии «genre» 2 is_tax( 'genre' )
taxonomy.php Общий шаблон для всех таксономий 3 is_tax()
category.php / tag.php Встроенные рубрики и метки 4 is_category() / is_tag()
archive.php Любой архив сайта 5 is_archive()
index.php Резервный вывод, если ничего не найдено 6 — последний всегда

Приоритет работает по принципу «чем точнее имя файла, тем раньше он выбирается». Поэтому не стоит заводить десяток файлов «на всякий случай»: один taxonomy-genre.php плюс общий archive.php закрывают почти все задачи типового сайта.

Частые ошибки при работе с шаблонами таксономий

Даже опытные разработчики нередко спотыкаются на архивах терминов — просто потому, что поведение WordPress здесь неочевидно. Вот ошибки, которые встречаются чаще всего:

  • Неверное имя файла. Файл taxonomy-zhanny.php не сработает, если машинное имя таксономии — genre. Имя файла всегда берётся из register_taxonomy(), а не из отображаемого ярлыка.
  • Шаблон лежит не в той теме. WordPress ищет файл в активной теме и её родителе. Файл, положенный в папку исходной темы из архива, никакого эффекта не даст.
  • Не сброшены постоянные ссылки. Сменили слаг таксономии и получили 404? Откройте «Настройки → Постоянные ссылки» и сохраните их.
  • Забыт wp_reset_postdata(). После кастомного WP_Query последующие функции выводят данные чужой записи.
  • Отсутствует параметр paged. Вторая страница архива показывает те же записи, что и первая.
  • Нет проверки на WP_Error. get_terms() и get_term_link() могут вернуть ошибку, и без проверки страница выдаст предупреждение PHP.
  • Ожидание taxonomy-category.php. Для рубрик и меток используются файлы category.php и tag.php, а не имена встроенных таксономий.

Полезно понимать, что архивы терминов тесно связаны с хуками: например, добавить поле в админке термина можно на хуке edited_terms, а изменить вывод — на фильтре get_the_terms. Основы работы с ними разобраны в статье про actions и filters в WordPress. И не забывайте: любой код лучше добавлять маленькими, изолированными кусками — подход к таким правкам хорошо описан в подборке про полезные сниппеты для functions.php.

TimeWeb

Частые вопросы о шаблонах таксономии в WordPress

Какой файл шаблона отвечает за архив терминов таксономии?

Основной файл — taxonomy-{таксономия}.php, например taxonomy-genre.php. Для одного конкретного термина можно создать более точный taxonomy-genre-fantasy.php. Если своего файла нет, WordPress по очереди пробует taxonomy.php, archive.php и в конце index.php. Имя файла должно совпадать с машинным именем таксономии из register_taxonomy().

Почему мой шаблон таксономии не подключается?

Проверьте три вещи. Первое: имя файла точно повторяет машинное имя таксономии, а не её отображаемый ярлык. Второе: файл лежит в папке активной темы или её родителя. Третье: после смены слага или регистрации таксономии сохранены постоянные ссылки — зайдите в «Настройки → Постоянные ссылки» и нажмите «Сохранить». Часто проблема именно в кэше переписывания ссылок.

Чем архив таксономии отличается от архива рубрики?

Технически это один и тот же тип страницы: список записей одного термина. Разница только в файлах шаблонов и условных тегах. Для рубрик и меток это category.php и tag.php с тегами is_category() и is_tag(). Для своих таксономий — taxonomy-{имя}.php с тегом is_tax(). Файл вида taxonomy-category.php для рубрик не сработает.

Как вывести список терминов таксономии со ссылками?

Используйте get_terms() с параметрами taxonomy и hide_empty => true, затем пройдитесь по массиву циклом foreach. Ссылку на архив термина даёт get_term_link( $term ), название — свойство $term->name, количество записей — $term->count. Обязательно проверяйте результат на is_wp_error() и экранируйте вывод через esc_url() и esc_html().

Почему на второй странице архива показываются те же записи?

Скорее всего вы выводите записи кастомным WP_Query без параметра paged. Добавьте его: 'paged' => max( 1, get_query_var( 'paged' ) ), а в навигацию передайте 'total' => $query->max_num_pages. Без номера страницы WordPress считает, что вы всегда на первой. В стандартном цикле have_posts() эта проблема не возникает — он уже знает номер страницы.

Можно ли добавить картинку или метаполе к термину таксономии?

Да. С версии WordPress 4.4 у терминов есть метаполя: читают их через get_term_meta(), записывают через update_term_meta(), удаляют через delete_term_meta(). Для картинки удобно хранить ID вложения, например в поле term_image_id, и выводить через wp_get_attachment_image(). Проще всего создавать такие поля в плагине ACF — там есть отдельный тип размещения «Таксономия».

Вывод

Архив терминов — это не отдельная страница, а автоматически формируемый вывод WordPress, и вся работа с ним сводится к правильному файлу-шаблону. Достаточно запомнить иерархию: taxonomy-{таксономия}-{термин}.php, затем taxonomy-{таксономия}.php, taxonomy.php, archive.php и index.php. Имя файла берётся из register_taxonomy(), а не из отображаемого названия, — на этом спотыкается большинство новичков.

Для стандартного архива хватает обычного цикла have_posts() и the_posts_pagination(). Кастомный WP_Query с tax_query нужен только там, где требуется своя выборка и сортировка — и тогда не забывайте про paged и wp_reset_postdata(). Список терминов со ссылками выводится через get_terms() и get_term_link(), а описание термина и метаполя добавляют архиву уникальный контент, что важно для SEO.

Если добавлять код и настраивать шаблоны некогда, это можно поручить команде, которая делает сайты на WordPress под ключ: мы настраиваем темы, свои типы записей и таксономии, выводим архивы и каталоги, а после запуска сопровождаем проект. Посмотрите услуги разработки и продвижения, изучите портфолио выполненных проектов и почитайте блог о сайтах и продвижении. Ещё полезно свериться с технической базой: например, материал про настройку SEO-плагина и XML-карту сайта для Яндекса и Google. Обсудить задачу и получить смету можно через форму контактов — подберём решение под ваш проект и бюджет.

Clearfy

Поделиться:
Telegram ВКонтакте