Эта статья — вторая часть полного Руководства по кастомным типам записей WordPress. Прежде чем погрузиться с головой в чтения данного практического руководства, пробегитесь взглядом по первоначальному уроку касательно настраиваемых типов публикаций Custom Post Types (далее сокращенно — CPT) для понимания базовых принципов и возможностей.

Скачать исходники |

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

Настраиваем таксономию для собственных типов публикаций

Таксономия позволяет отличным образом группировать различные объекты и поможет нам находить посты, которые относятся к конкретной группе опубликованных на сайте материалов. Обычно в WordPress используется для такой систематизации принадлежность записей к Рубрикам либо отбор по Меткам. Мы же создадим настраиваемую таксономию для своих CPT.

Шаг 1. Регистрируем настраиваемую функцию

Открываем файл плагина (см. предыдущий урок, в нашем случае это Movie-Reviews.php) и добавляем в него следующий код для регистрации пользовательской функции:

add_action( 'init', 'create_my_taxonomies', 0 );

Шаг 2. Внедряем нашу функцию и регистрируем настраиваемую таксономию

function create_my_taxonomies() {
    register_taxonomy(
        'movie_reviews_movie_genre',
        'movie_reviews',
        array(
            'labels' => array(
                'name' => 'Movie Genre',
                'add_new_item' => 'Add New Movie Genre',
                'new_item_name' => "New Movie Type Genre"
            ),
            'show_ui' => true,
            'show_tagcloud' => false,
            'hierarchical' => true
        )
    );
}

Здесь функция register_taxonomy отвечает за всю важную работу касательно создания настраиваемой таксономии (или категории — как в нашем случае) с именем 'movie_reviews_movie_genre' для пользовательского типа постов 'movie_reviews' (в качестве примера нам служит сайт с обзорами и отзывами о кинофильмах). Ярлыки определяют разные строки, которые используются в секции администрирования таксономии:

  • 'show_ui' => true используется для включения редактора таксономии в панели управления.
  • 'show_tagcloud' => false служит для отключения облака тегов.
  • 'hierarchical' => true отвечает за формат настраиваемой таксономии.

Примечание: 'hierarchical' => false отвечает за конверсию рубрик в теги.

Шаг 3. Отображение настраиваемой таксономии

После сохранения файла Movie-Reviews.php откройте свой файл с настраиваемым шаблоном — в нашем случае речь идет о файле single-movie_reviews.php — и добавьте в него следующий выделенный цветом код для включения категорий для наших постов:

<?php
 /*Template Name: New Template
 */
get_header(); ?>
<div id="primary">
    <div id="content" role="main">
     <?php $mypost = array( 'post_type' => 'movie_reviews', );
      $loop = new WP_Query( $mypost ); ?>
      <!-- Cycle through all posts -->
      <?php while ( $loop->have_posts() ) : $loop->the_post();?>
          <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
              <header class="entry-header">
                <!-- Display featured image in top-aligned floating div -->
                 <div style="float: top; margin: 10px">
                    <?php the_post_thumbnail( array( 100, 100 ) ); ?>
                 </div>
                 <!-- Display Title and Author Name -->
                 <strong>Title: </strong><?php the_title(); ?><br />
                 <strong>Director: </strong>
                 <?php echo esc_html( get_post_meta( get_the_ID(), 'movie_director', true ) ); ?>
                 <br />
                <strong>Genre: </strong>
                <?php
                the_terms( $post->ID, 'movie_reviews_movie_genre' ,  ' ' );
                    ?>
<br />
                 <!-- Display yellow stars based on rating -->
                <strong>Rating: </strong>
                <?php
                $nb_stars = intval( get_post_meta( get_the_ID(), 'movie_rating', true ) );
                for ( $star_counter = 1; $star_counter <= 5; $star_counter++ ) {
                    if ( $star_counter <= $nb_stars ) {
                        echo '<img src="' . plugins_url( 'Movie-Reviews/images/icon.png' ) . '" />';
                    } else {
                        echo '<img src="' . plugins_url( 'Movie-Reviews/images/grey.png' ). '" />';
                    }
                }
                ?>
              </header>
              <!-- Display movie review contents -->
              <div class="entry-content">
                   <?php the_content(); ?>
              </div>
              <hr/>
         </article>
   <?php endwhile;  ?>
   </div>
</div>
<?php wp_reset_query(); ?>
<?php get_footer(); ?>

Шаг 4. Что получилось

Вот мы добавили настраиваемую таксономию Movie Genre для наших постов с обзорами кинофильмов. Теперь мы сможем добавлять новые категории из админ-панели и назначать эти категории для наших CPT.

Отображение дополнительных столбцов

На странице с администрируемым списком WordPress CPT по умолчанию есть 2 колонки: Date и Comments, которые отвечают за сортировку наших пользовательских записей. Чтобы добавить другие столбцы и включить сортировку для них, выполните следующие пошаговые действия.

Шаг 1. Регистрируем функцию

Откройте файл плагина Movie-Reviews.php и добавьте в него следующую строку кода для регистрации функции, вызываемой при подготовке перечня обзоров кинофильмов:

add_filter( 'manage_edit-movie_reviews_columns', 'my_columns' );

Здесь мы применили переменный фильтр manage_edit-(Custom_Post_Type)_columns, который передает список постов в столбце как аргумент в нашу функцию.

Шаг 2. Внедряем функцию

function my_columns( $columns ) {
    $columns['movie_reviews_director'] = 'Director';
    $columns['movie_reviews_rating'] = 'Rating';
    unset( $columns['comments'] );
    return $columns;
}

Мы добавили 2 колонки: Director и Rating. Они появятся в админ-панели для CPT. Также мы удалили колонку Comments из нашего списка.

Шаг 3. Наполняем столбцы

Регистрируем функцию для наполнения столбцов.

add_action( 'manage_posts_custom_column', 'populate_columns' );

Шаг 4. Внедрение

function populate_columns( $column ) {
    if ( 'movie_reviews_director' == $column ) {
        $movie_director = esc_html( get_post_meta( get_the_ID(), 'movie_director', true ) );
        echo $movie_director;
    }
    elseif ( 'movie_reviews_rating' == $column ) {
        $movie_rating = get_post_meta( get_the_ID(), 'movie_rating', true );
        echo $movie_rating . ' stars';
    }
}

Здесь функция проверяет, какие из запрошенных колонок есть, прежде чем обратиться к ним. Мы использовали функцию get_the_ID() для определения текущего ряда и и далее для передачи данных в get_post_meta для запроса содержимого из конкретного столбца.

Шаг 5. Регистрация колонок как сортируемых списков

Теперь давайте зарегистрируем функцию, которая будет вызываться, когда WordPress идентифицирует сортируемые столбцы в CPT.

add_filter( 'manage_edit-movie_reviews_sortable_columns', 'sort_me' );

Шаг 6. Внедрение

function sort_me( $columns ) {
    $columns['movie_reviews_director'] = 'movie_reviews_director';
    $columns['movie_reviews_rating'] = 'movie_reviews_rating';
    return $columns;
}

Эта функция идентифицирует 2 колонки, которые будут отсортированы, а затем возвращает массив данных. Но на этом этапе работа еще не завершена.

Шаг 7. Упорядочиваем по выбранному полю

add_filter( 'request', 'column_ordering' );
add_filter( 'request', 'column_orderby' );
function column_orderby ( $vars ) {
    if ( !is_admin() )
        return $vars;
    if ( isset( $vars['orderby'] ) && 'movie_reviews_director' == $vars['orderby'] ) {
        $vars = array_merge( $vars, array( 'meta_key' => 'movie_director', 'orderby' => 'meta_value' ) );
    }
    elseif ( isset( $vars['orderby'] ) && 'movie_reviews_rating' == $vars['orderby'] ) {
        $vars = array_merge( $vars, array( 'meta_key' => 'movie_rating', 'orderby' => 'meta_value_num' ) );
    }
    return $vars;
}

Приведенная выше функция связана с фильтром запросов и добавляет элементы к массиву запросов на основе переменных, определенных в запрашиваемом URL. Сам по себе WordPress "не знает", как упорядочить наши посты согласно выборке полей Movie Director или Movie Rating, так что нам придется "научить" наш WordPress, как это сделать. Для этой цели нам и нужна данная функция.

Мы успешно добавили 2 сортируемых колонки в секцию администрирования:

Создаем фильтры для настраиваемой таксономии

Здесь мы увидим, как настраиваемая таксономия (в нашем случае — это категории) может быть использована в качестве дополнительного фильтра при составлении списка CPT в секции администрирования WordPress, чтобы администраторы могли отобразить элементы CPT, принадлежащие к конкретной категории.

Шаг 1. Регистрация функции

Откройте файл плагина и добавьте в него следующий код для регистрации функции. Эта функция будет вызвана, когда WordPress будет готовиться к отображению выпадающего списка с результатами фильтрации контента.

add_action( 'restrict_manage_posts', 'my_filter_list' );

Шаг 2. Внедрение функции

function my_filter_list() {
    $screen = get_current_screen();
    global $wp_query;
    if ( $screen->post_type == 'movie_reviews' ) {
        wp_dropdown_categories( array(
            'show_option_all' => 'Show All Movie Genres',
            'taxonomy' => 'movie_reviews_movie_genre',
            'name' => 'movie_reviews_movie_genre',
            'orderby' => 'name',
            'selected' => ( isset( $wp_query->query['movie_reviews_movie_genre'] ) ? $wp_query->query['movie_reviews_movie_genre'] : '' ),
            'hierarchical' => false,
            'depth' => 3,
            'show_count' => false,
            'hide_empty' => true,
        ) );
    }
}

Мы использовали глобальную переменную, чтобы узнать, какой тип поста отображать, а также использовать запрос к посту для проверки его на совпадение с уже существующими фильтрами. Функция wp_dropdown_categories применяется для отображения всех типов таксономии, которые зарегистрированы в разделе Movie Genres.

Аргументы orderby, show_count, hide_empty, depth и другие определяют сортировку, отображение счетчиков числа постов в каждой категории, скрывают не связанные с ними категории, определяют максимальную глубину для отображения в иерархической структуре категорий.

Шаг 3. Отображение фильтрованных результатов

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

add_filter( 'parse_query','perform_filtering' );

Шаг 4. Внедрение функции отображения контента

function perform_filtering( $query ) {
    $qv = &$query->query_vars;
    if ( ( $qv['movie_reviews_movie_genre'] ) && is_numeric( $qv['movie_reviews_movie_genre'] ) ) {
        $term = get_term_by( 'id', $qv['movie_reviews_movie_genre'], 'movie_reviews_movie_genre' );
        $qv['movie_reviews_movie_genre'] = $term->slug;
    }
}

Функция perform_filtering получает объект запроса на конкретный пост от WordPress, а затем переводит запрос и отображает контент согласно набору переменных, содержащихся в теле объекта. Также на данном этапе происходит верификация того, является ли параметр Movie Genre частью запрашиваемых переменных, и только потом происходит выполнение запроса. Теперь вы сможете использовать фильтр для отображения кинофильмов по жанрам:

Последнее по порядку, но не по значимости: Создаем страницу архива

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

Шаг 1. Создаем для архива путь для перехода и вызова

Откройте файл плагина Movie-Reviews.php и добавьте выделенный цветом код в функцию include_template_function:

function include_template_function( $template_path ) {
    if ( get_post_type() == 'movie_reviews' ) {
        if ( is_single() ) {
            // checks if the file exists in the theme first,
            // otherwise serve the file from the plugin
            if ( $theme_file = locate_template( array ( 'single-movie_reviews.php' ) ) ) {
                $template_path = $theme_file;
            } else {
                $template_path = plugin_dir_path( __FILE__ ) . '/single-movie_reviews.php';
            }
        }
        elseif ( is_archive() ) {
            if ( $theme_file = locate_template( array ( 'archive-movie_reviews.php' ) ) ) {
                $template_path = $theme_file;
            } else { $template_path = plugin_dir_path( __FILE__ ) . '/archive-movie_reviews.php';
            }
        }
    }
    return $template_path;
}

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

Шаг 2. Создаем шаблон архива

Сохраните и закройте файл плагина и затем создайте новый файл под названием archive-movie_reviews.php. Вставьте в него следующий код:

<?php get_header(); ?>
<section id="primary">
    <div id="content" role="main" style="width: 70%">
    <?php if ( have_posts() ) : ?>
        <header class="page-header">
            <h1 class="page-title">Movie Reviews</h1>
        </header>
        <table>
            <!-- Display table headers -->
            <tr>
                <th style="width: 200px"><strong>Title</strong></th>
                <th><strong>Director</strong></th>
            </tr>
            <!-- Start the Loop -->
            <?php while ( have_posts() ) : the_post(); ?>
                <!-- Display review title and author -->
                <tr>
                    <td><a href="<?php the_permalink(); ?>">
                    <?php the_title(); ?></a></td>
                    <td><?php echo esc_html( get_post_meta( get_the_ID(), 'movie_director', true ) ); ?></td>
                </tr>
            <?php endwhile; ?>
            <!-- Display page navigation -->
        </table>
        <?php global $wp_query;
        if ( isset( $wp_query->max_num_pages ) && $wp_query->max_num_pages > 1 ) { ?>
            <nav id="<?php echo $nav_id; ?>">
                <div class="nav-previous"><?php next_posts_link( '<span class="meta-nav">&larr;</span> Older reviews'); ?></div>
                <div class="nav-next"><?php previous_posts_link( 'Newer reviews <span class= "meta-nav">&rarr;</span>' ); ?></div>
            </nav>
        <?php };
    endif; ?>
    </div>
</section>
<br /><br />
<?php get_footer(); ?>

Мы используем здесь цикл для того, чтобы провести поиск по всем постам и отобразить их в формате таблицы. Также мы тут определили навигационное меню для того, чтобы определить, не больше ли у нас постов, чем указано в настройках WordPress. Навигационные меню отображаются благодаря функциям next_post_links и previous_post_links.

Мы также использовали объект wp_query, в котором содержатся данные об исполняемом в данный момент запросе в порядке рендеринга требуемых элементов и содержимого страницы. Функция get_post_meta использовалась для получения данных из настраиваемых полей.

Шаг 3. Что получилось в итоге

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

Вот мы и завершили "путешествие" по нашему практическому руководству. Надеемся, что мы смогли вас убедить в значительной роли и больших возможностях настраиваемых типов записей. Есть немало возможностей для их практического применения, поэтому советуем вам самим экспериментировать с настраиваемыми постами. И, как всегда, будем рады отзывам и мнениям в комментариях к этой публикации.

Источник: WP.tutsplus.com

Вам понравился материал?

Добавить комментарий

Такой e-mail уже зарегистрирован. Воспользуйтесь формой входа или введите другой.

Вы ввели некорректные логин или пароль

Извините, для комментирования необходимо войти.

8 комментариев

сначала новые
по рейтингу сначала новые по хронологии
Евгений

Доброго времени суток. Помогите, пожалуйста.
Я с помощью Toolset создал тип публикаций условно: «Публикация», к ней создал систематику: «Рубрика Публикаций «и связал их вместе, после чего вывел на странице page-public.php в виде постов. В «Рубрика Публикаций» имеются подкатегории, которые я и хочу отдельно вывести блоками, как это реализовать ? поскольку у меня выводятся все записи созданной систематики. заранее благодарен

Александр

Не показываются посты в категориях, както оно не правильно в категориях, где может быть проблема?

Добрый день!

А как сделать так, чтобы к каталогу фильмов на произвольных типах записи любой мог добавлять новые объекты-фильмы не из админки (из фронтенда)?

Андрей

Добрый день, подскажите, как для дополнительных таксономий прописать уникальный заголовок, и мета данные такие, как ключевые слова и описание. Желательно, чтоб это реализовать без плагинов. У меня установлен плагин "platinum seo pack" и там есть возможность прописать title но только для одной таксономии, а у меня их несколько.

Ilya Colley

Как мне кажется, в тексте статьи есть опечатка при создании сортируемых списков по колонкам в Шаге 7.Упорядочиваем по выбранному полю указан фильтр add_filter( 'request', 'column_ordering' );

Однако функция 'column_ordering' не определена ни здесь, ни в других частях кода WordPress'а. В результате пример не работает и часть записей, имеющих рубрики, пропадает...
Точно так же он не работает и в зарубежных форумах, где он используется юзерами...

Хотелось бы поправить :)

Александр

Здравствуйте, делаю сайт с "нашими работами", есть четыре типа записей, вывести их вывел, а вот как загнать их в один пункт админ-меню, не знаю((((

Сергей

Очень познавательная статья, большое спасибо автору! Но вот не понял, как добавить в пользовательскую таксономию возможность добавления картинки? Такое вообще возможно?

Конечно возможно.

Используйте плагин: ACF http://wordpress.org/plugins/advanced-custom-fields/

И будет Вам счастье =)