Russian (Pусский) translation by Ellen Nelson (you can also view the original English article)

Иногда вы хотите, чтобы на вашем WordPress сайте, под записью в блоге отображалось больше страниц, нежели просто блог.
У вас уже есть возможность использовать категории, архивы таксономии и метки. Этого достаточно, чтобы разделить ваше содержимое и добавить различные разделы в ваш блог или новостной сайт.
Но, иногда могут потребоваться записи, связанные с текущей записью. Хорошим примером послужит магазин. Продукты в вашем магазине являются настраиваемыми типом содержимого, и чтобы продать эти товары, вам нужно написать запись в блоге об этих товарах.
В этом уроке, я покажу вам как добавить список схожих записей на каждую страницу для пользовательского типа содержимого. Я сделаю это используя таксономию, чьи термины будут соответствовать названиям продуктов, о которых вы хотите написать пост. Я покажу вам, как назначить таксономию и на продукт, и к обычному посту, и как использовать эту связь для вывода списка записей на отдельной странице продукта.
Что вам понадобится
Чтобы следовать вместе со мной, вам понадобится:
- Установленный WordPress для разработок, не следует делать это на рабочем сайте, пока это не будет работать.
- Редактор кода.
- Тема, которую вы можете редактировать или тема с хуком действий (action) внизу содержимого. Если вы используете стороннюю тему без хуков, вам понадобиться создать дочернюю тему и редактировать её.
Настройка плагина
Начнём с создания нового плагина и добавления к нему «шапки» с информацией:
<?php /** * Plugin Name: Tuts+ Add Taxonomy Archive to Custom Post Types * Plugin URI: https://github.com/rachelmccollin/tutsplus-custom-post-type-taxonomy-archive * Description: Uses a custom taxonomy to add relevant blog posts to custom post type pages * Version: 1.0 * Author: Rachel McCollin * Textdomain: tutsplus * Author URI: https://rachelmccollin.com * */
Если вам это не знакомо, посмотрите наш курс по созданию плагина. И не стесняйтесь изменять текст в «шапке» выше, подставьте ваше имя, URI и прочее.
Регистрация типа содержимого
Если вы работаете с типом содержимого, не зарегистрированного другим плагином на вашем сайте, тогда вам нужно его зарегистрировать.
Мы сделаем это создав функцию и подцепив её к хуку init
. Добавьте это в ваш плагин:
function tutsplus_register_product_post_type() { // book blurbs $labels = array( 'name' => __( 'Products' ), 'singular_name' => __( 'Product' ), 'add_new' => __( 'New Product' ), 'add_new_item' => __( 'Add New Product' ), 'edit_item' => __( 'Edit Product' ), 'new_item' => __( 'New Product' ), 'view_item' => __( 'View Product' ), 'search_items' => __( 'Search Products' ), 'not_found' => __( 'No Products Found' ), 'not_found_in_trash' => __( 'No Products found in Trash' ), ); $args = array( 'labels' => $labels, 'has_archive' => true, 'public' => true, 'hierarchical' => false, 'supports' => array( 'title', 'editor', 'excerpt', 'custom-fields', 'thumbnail', 'page-attributes' ), 'rewrite' => array( 'slug' => 'product' ), ); register_post_type( 'tutsplus_product', $args ); } add_action( 'init', 'tutsplus_register_product_post_type' );
Это регистрирует плагин tutsplus_product
. Если хотите иное название для типа содержимого, тогда измените его в коде выше.
Теперь, когда вы посетите админку WordPress, вы увидите в меню ваш тип содержимого:
Регистрация таксономии
Следующий шаг – регистрация таксономии. Снова создаём функцию в нашем плагине:
function tutsplus_register_product_taxonomy() { // product taxonomy $labels = array( 'name' => __( 'Products', 'tutsplus' ), 'singular_name' => __( 'Product', 'tutsplus' ), 'search_items' => __( 'Search Products', 'tutsplus' ), 'all_items' => __( 'All Products', 'tutsplus' ), 'edit_item' => __( 'Edit Product', 'tutsplus' ), 'update_item' => __( 'Update Product', 'tutsplus' ), 'add_new_item' => __( 'Add New Product', 'tutsplus' ), 'new_item_name' => __( 'New Product Name', 'tutsplus' ), 'menu_name' => __( 'Product Taxonomy Term', 'tutsplus' ), ); $args = array( 'labels' => $labels, 'hierarchical' => true, 'sort' => true, 'args' => array( 'orderby' => 'term_order' ), 'rewrite' => array( 'slug' => 'book' ), 'show_admin_column' => true ); register_taxonomy( 'tutsplus_product_tax', array( 'tutsplus_product', 'post', 'page' ), $args); } add_action( 'init', 'tutsplus_register_product_taxonomy' );
Моя таксономия называется tutsplus_product_tax
. Я специально добавила tax
, чтобы знать, что это таксономия, а не тип содержимого. А ещё я сделала специальный пункт меню так, чтобы кто бы ни использовал этот плагин через админку WordPress, они будет знать когда они работают с типом содержимого, а когда с таксономией.
Вот оно в админке WordPress:

На снимке вы можете увидеть, что я добавила несколько примеров продуктов.
Создание запроса
Переходим к самому интересному. Нам нужно написать функцию, которая будет получать термины таксономии для продукта, а затем выводить список постов, которые также содержат этот термин.
Чтобы это сделать, используем функцию get_the_terms()
. Затем, мы создадим пустой массив переменных и добавим порцию каждого полученного термина в этот массив. Мы можем использовать этот массив в качестве аргументов для WP_Query
.
Начнём с открытия новой функции и проверки, чтобы убедиться, что мы находимся на отдельной странице для нашего типа содержимого. Если вы задали вашему типу содержимого другое название, или используете уже зарегистрированный тип другой темой, то в этом коде, вам надо заменить 'tutsplus_product'
на ваш тип содержимого.
function tutsplus_add_posts_to_product_pages() { // check if we're in the product post type if( is_singular( 'tutsplus_product' ) ) { } }
Получение списка терминов или добавление их в массив
Теперь, а нашей функции (внутри проверки, что мы находимся на странице отдельного товара) нам нужно получить список терминов таксономии для этой записи.
Добавьте это:
$productterms = get_the_terms( get_the_ID(), 'tutsplus_product_tax' );
Теперь нужно пройтись через все термины и добавить их в массив переменных. Но это делается только, если предыдущая функция возвращает список терминов, поэтому обернём это в проверку того, что $productterms
присутствует.
if( $productterms ) { $producttermnames[] = 0; foreach( $productterms as $productterm ) { $producttermnames[] = $productterm->name; } }
Это извлекает фрагмент каждого термина и добавляет его в массив $producttermnames
.
Выполняем запрос
Теперь, нам надо задать аргументы запроса. Это будет внутри условия if( $productterms )
, так как мы не хотим, чтобы он выполнялся при отсутствии терминов таксономии. Добавьте это в ваш код:
$args = array ( 'post_type' => 'post', 'tax_query' => array( array( 'taxonomy' => 'tutsplus_product_tax', 'field' => 'slug', 'terms' => $producttermnames, ), ), );
Тут, мы использовали массив $producttermnames
с аргументами tax_query
. Это выберет любые записи с любыми терминами, которые есть в этом продукте.
Теперь запустим запрос с этими аргументами:
if( $query->have_posts() ) { ?> <section class="product-related-posts"> <?php echo '<h2>' . __( 'Related Posts', 'tutsplus' ) . '</h2>'; ?> <ul class="product-posts"> <?php while ( $query->have_posts() ) : $query->the_post(); ?> <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li> <?php endwhile; ?> <?php wp_reset_postdata(); ?> </ul> </section> <?php }
Это выведет элемент h2
с заголовком и список со ссылками на каждый пост. Если пожелаете, можете вывести это по-другому; можете добавить отрывок или изображение.
Как избежать ошибок
Обычно, вы не думаете, что пользователь добавит больше одного термина таксономии к каждому продукту, потому что каждый термин связан с продуктом. Но нельзя сказать наверняка, что такого никогда не случится. Вот почему мы добавили массив $producttermslist
в функцию и используем его для одного экземпляра WP_Query
, вместо запуска WP_Query
в цикле foreach
. Также это делает страницу более эффективной, так как выполняется только один дополнительный запрос.
Вся функция
Вот вся функция полностью, со всеми скобками:
function tutsplus_add_posts_to_product_pages() { // check if we're in the product post type if( is_singular( 'tutsplus_product' ) ) { // fetch taxonomy terms for current product $productterms = get_the_terms( get_the_ID(), 'tutsplus_product_tax' ); if( $productterms ) { $producttermnames[] = 0; foreach( $productterms as $productterm ) { $producttermnames[] = $productterm->name; } // set up the query arguments $args = array ( 'post_type' => 'post', 'tax_query' => array( array( 'taxonomy' => 'tutsplus_product_tax', 'field' => 'slug', 'terms' => $producttermnames, ), ), ); // run the query $query = new WP_Query( $args ); if( $query->have_posts() ) { ?> <section class="product-related-posts"> <?php echo '<h2>' . __( 'Related Posts', 'tutsplus' ) . '</h2>'; ?> <ul class="product-posts"> <?php while ( $query->have_posts() ) : $query->the_post(); ?> <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li> <?php endwhile; ?> <?php wp_reset_postdata(); ?> </ul> </section> <?php } } } }
Запускаем функцию
Пока что, эта функция ничего не делает. Чтобы она заработала, вам нужно сделать одну из трёх вещей:
- Подцепить её к существующему хуку действий в вашей теме.
- Добавить хук действий в вашу тему, используя
do_action()
и подцепив её туда. - Добавить название функции в вашу тему туда, где вы хотите вывести этот список.
Для второго и третьего варианта, если вы работаете со сторонней темой, вам придётся создать дочернюю тему и редактировать её. Ещё вы можете создать файл шаблона single-tutsplus_product.php и добавить хук или функцию в него, или просто добавить это в single.php. Если вы подцепили её через файл шаблона для типа содержимого, то вы можете удалить проверку if ( is_singular( 'tutsplus_product' ) )
.
Я использую тему Suki из каталога плагинов WordPress. У неё в файле single.php есть данный хук:
do_action( 'suki/frontend/after_main' );
Хук находится прямо под содержимым, именно там, где я хочу вывести мой список. Поэтому я цепляю мою функцию к этому хуку действий:
add_action( 'suki/frontend/after_main', 'tutsplus_add_posts_to_product_pages' );
Когда вы это сделаете, сохраните ваш плагин и добавьте несколько продуктов и терминов таксономии.
Результат
Я добавила термин widget в продукт Widget и другой термин для демонстрации:
Я добавила эти два термина к нескольким записям на моем сайте, так что при просмотре страницы товара Widget, внизу, вы можете видеть список связанных записей:
Этот список записей поможет посетителям посмотреть записи в блоге, связанные с этим продуктом и это, поспособствует тому, что они узнают больше о товаре и (надеюсь) приобретут его.
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post