Создание страницы «О команде разработчиков» в WordPress
Почти каждая тема (theme), которую я разрабатывал для WordPress, требует наличия окна с информации о команде разработчиков. Навскидку, я сделал около 50 различных тем. Я подумал, что множество других WordPress-разработчиков также создают темы.
По этой причине, я хочу поделиться подходом, который я применяю при создании страницы «О команде разработчиков» в WordPress.

Те, кто просто хочет получить конечный результат, могут нажать кнопки ниже.
Просмотреть пример
Создание и управление страницей с информацией о разработчиках в WordPress требует использования следующих средств:
- Собственный тип записи, отличный от стандартных (например, team);
- Собственная таксономия для фильтрации (например, department);
- Метабоксы (metabox) для управления кастомными (созданными вами) полями (custom fields) ввода данных (например, position, email, phone и social media links).
Используя эти инструменты, в данной статье мы пройдем через все этапы процесса создания шаблона (template) страницы «О команде разработчиков» для нашей WordPress-темы.
- Для начала
- Создания собственного типа записи и таксономии
- Создание типа записи
- Создание таксономии (опционально)
- Метабокс для кастомных полей
- Заметка
- Кастомный шаблон
- Вывод записей о разработчиков на экран
- Примечание касательно производительности
- Стилизация шаблона с помощью CSS
- Условная проверка перед подключением CSS
- Примеры таблиц стилей
- Заключение
Для начала
Перед тем, как мы начнем, я хочу прояснить вам некоторые вещи. Приведенная выше ссылка, содержит примеры для данной статьи, в которых я применил объектно-ориентрованный подход и сохранил весь код в отдельном php-файле, который можно включать в файл functions.php своих тем.
Для ясности, я буду описывать весь процесс по шагам, и буду показывать, какие изменения надо вносить в файл functions.php.
Создания собственного типа записи и таксономии
Первым делом, нам необходимо зарегистрировать новый тип записи (например, team). Также, можете зарегистрировать собственный тип таксономии (например, department), если требуется фильтрация или категоризация.
Данный тип записи будет добавлять новое меню Team Profiles в административную панель WordPress, отделяя все записи, касающиеся команды разработчиков от стандартных записей и страниц (Posts и Pages), для упрощения управления ими.
Таксономия будет добавлять созданную нами категорию к записям типа «team», позволяя фильтровать и упорядочивать всю команду. Это очень полезно, когда у вас в команде более 10 человек. Также, это удобно для упорядочивания участников команды по местонахождению или отделу.

Создание типа записи
/**
* Регистрация типа записи `team`
*/
function team_post_type() {
// массив меток для полей и кнопок
$labels = array(
'name' => _x("Team", "post type general name"),
'singular_name' => _x("Team", "post type singular name"),
'menu_name' => 'Team Profiles',
'add_new' => _x("Add New", "team item"),
'add_new_item' => __("Add New Profile"),
'edit_item' => __("Edit Profile"),
'new_item' => __("New Profile"),
'view_item' => __("View Profile"),
'search_items' => __("Search Profiles"),
'not_found' => __("No Profiles Found"),
'not_found_in_trash' => __("No Profiles Found in Trash"),
'parent_item_colon' => ''
);
// Регистрация типа записи
register_post_type('team' , array(
'labels' => $labels,
'public' => true,
'has_archive' => false,
'menu_icon' => get_stylesheet_directory_uri() . '/lib/TeamProfiles/team-icon.png',
'rewrite' => false,
'supports' => array('title', 'editor', 'thumbnail')
) );
}
add_action( 'init', 'team_post_type', 0 );
Создание таксономии (опционально)
/**
* Регистрация таксономии `department`
*/
function team_taxonomy() {
// массив меток для полей и кнопок
$singular = 'Department';
$plural = 'Departments';
$labels = array(
'name' => _x( $plural, "taxonomy general name"),
'singular_name' => _x( $singular, "taxonomy singular name"),
'search_items' => __("Search $singular"),
'all_items' => __("All $singular"),
'parent_item' => __("Parent $singular"),
'parent_item_colon' => __("Parent $singular:"),
'edit_item' => __("Edit $singular"),
'update_item' => __("Update $singular"),
'add_new_item' => __("Add New $singular"),
'new_item_name' => __("New $singular Name"),
);
// Регистрация и прикрепление таксономии к типу записи 'team'
register_taxonomy( strtolower($singular), 'team', array(
'public' => true,
'show_ui' => true,
'show_in_nav_menus' => true,
'hierarchical' => true,
'query_var' => true,
'rewrite' => false,
'labels' => $labels
) );
}
add_action( 'init', 'team_taxonomy', 0 );
В этом примере, мы используем таксономию department не для всех элементов. Я включил это в статью потому, что полезно понимать, как это можно использовать для фильтрации членов команды.
Метабокс для кастомных полей
Теперь, у нас есть новый пункт меню в WordPress - «Профили участников команды» - и нам нужно определиться с данными, которые мы хотим хранить в записи о каждом участнике команды. Исходя из моего опыта, предлагаю использовать следующие поля:
- Расположение (отдел);
- Электронная почта;
- Телефон;
- Страница в Twitter;
- Страница в LinkedIn.
Чтобы управлять данными полями, нужно создать кнопки «Добавить новую запись» (Add New) и «Редактировать» (Edit), которые позволят администраторам сайта и авторам интуитивно просто добавлять и обновлять эту информацию.
Для создания кастомных метабоксов с полями я использую плагин Advanced Custom Fields (ACF).

Чтобы создать этот метабокс, вам понадобится установленный плагин ACF, который позволяет создавать собственные поля через пункт меню Custom Fields, расположенный слева в панели администрирования. На изображении ниже можно видеть поля, которые я использовал для примера, изложенного в этой статье.

Если вы такой же ленивый (а точнее экономящий время), как я, можете воспользоваться импортом XML-файла, чтобы автоматизировать процесс создания полей. Вот пошаговая инструкция:
- Скачайте файл «Информация о команде» со списком нужных полей: acf-export-team-details.xml.zip;
- Перейдите в Инструменты (Tools) > Импорт (Import) и выберите WordPress;
- Установите плагин импорта WP, если будет предложено;
- Загрузите и импортируйте xml-файл;
- Выберите пользователя и проигнорируйте возможность импорта вложений.
Готово!
Плагин ACF хранит данные внутри записей, поэтому можно использовать стандартный инструмент WordPress для импорта XML. Очень умный ход со стороны разработчика плагина, Elliot Condon.
Заметка
В моем PHP-классе я добавил административное сообщение, которое предлагает установить плагин ACF, если он еще не установлен. Это полезно, чтобы напомнить вам о необходимости использования данного плагина для правильной работы.
Кастомный шаблон
На данный момент мы имеем настроенную систему управления, но нам также необходимо вывести информацию на сайт. Чтобы это сделать, я обычно создаю кастомный шаблон темы (например, template-team.php), который меняет вид определенной страницы WordPress. Чтобы узнать об этом более подробно, ознакомьтесь с официальной документацией WordPress.org по вопросу кастомных полей.
Вывод записей о разработчиков на экран
Чтобы выводить записи о нашей команде внутри кастомного шаблона, мы используем следующий код:
<?php
/**
* Template Name: Team
*/
the_post();
// Получаем записи типа 'team'
$team_posts = get_posts( array(
'post_type' => 'team',
'posts_per_page' => -1, // Неограниченное количество записей
'orderby' => 'title', // Упорядочиваем по алфавиту
) );
if ( $team_posts ):
?>
<section class="row profiles">
<div class="intro">
<h2>О команде разработчиков</h2>
<p class="lead">“Отдельные люди могут сделать многое, но команда - еще больше!”</p>
</div>
<?php
foreach ( $team_posts as $post ):
setup_postdata($post);
// Автоматическое изменение размеров иконок предпросмотра с помощью сервиса Photon
$thumb_src = null;
if ( has_post_thumbnail($post->ID) ) {
$src = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'team-thumb' );
$thumb_src = $src[0];
}
?>
<article class="col-sm-6 profile">
<div class="profile-header">
<?php if ( $thumb_src ): ?>
<img src="<?php echo $thumb_src; ?>" alt="<?php the_title(); ?>, <?php the_field('team_position'); ?>" class="img-circle">
<?php endif; ?>
</div>
<div class="profile-content">
<h3><?php the_title(); ?></h3>
<p class="lead position"><?php the_field('team_position'); ?></p>
<?php the_content(); ?>
</div>
<div class="profile-footer">
<a href="tel:<?php the_field('team_phone'); ?>"><i class="icon-mobile-phone"></i></a>
<a href="mailto:<?php echo antispambot( get_field('team_email') ); ?>"><i class="icon-envelope"></i></a>
<?php if ( $twitter = get_field('team_twitter') ): ?>
<a href="<?php echo $twitter; ?>"><i class="icon-twitter"></i></a>
<?php endif; ?>
<?php if ( $linkedin = get_field('team_linkedin') ): ?>
<a href="<?php echo $linkedin; ?>"><i class="icon-linkedin"></i></a>
<?php endif; ?>
</div>
</article><!-- /.profile -->
<?php endforeach; ?>
</section><!-- /.row -->
<?php endif; ?>
Чтобы автоматизировать процесс вывода профилей, я использовал функцию get_posts. Это простой эффективный метод. Я использовал следующие аргументы, чтобы оформить и упорядочить результаты выборки:
- 'post_type' => 'team' // будут показываться только записи этого типа;
- 'posts_per_page' => 50 // устанавливает ограничение на количество считываемых записей;
- 'orderby' => 'title' // упорядочивает результаты по имени;
- 'order' =>; 'ASC' // в возрастающем алфавитном порядке.
Получив объект с результатами выборки по отдельному профилю, мы можем зациклить этот процесс, пройдясь по всем имеющимся записям, а затем вывести полученные данные на страницу в виде HTML-разметки.
Функции get_field и the_field встроены плагин ACF. Это, наверно, две самые востребованные функции, которыми вы будете пользоваться в процессе работы. Они выводят значения полученных полей.
Теперь, закончив с циклом вывода, мы можем приступить к созданию новой страницы (Page) в WordPress, выбрав Team из выпадающего списка шаблонов. Когда вы заходите на эту страницу, то будете видеть список профилей своей команды.

Примечание касательно производительности
Без использования кэширования, данный кусок кода добавляет 26 выборок на одну страницу! Если у вас очень большой сайт, то крайне необходимо воспользоваться Transients API для кэширования вывода, при интенсивных пользовательских запросах вроде этого. Я включил статический метод display() в свой PHP-класс, который управляет процессом кэширования.
if ( $team_profiles = TeamProfiles::display() )
echo $team_profiles;
Метод display() использует буферизацию вывода и кэширование, чтобы сохранить сгенерированный ранее нашим циклом HTML-код с профилями членов команды разработчиков.
Используя данный подход, по сравнению с предыдущим вариантом без кэширования, мы имеем всего 1 запрос, сохраняя драгоценные вычислительные ресурсы, которые бы, в противном случае, были потрачены вхолостую на 25 лишних запросов к базе данных. Это также уменьшает первоначальную загрузку страницы до 400-500мс. Неплохо!
Стилизация шаблона с помощью CSS
Вуаля! Теперь у нас есть информация обо всей команде разработчиков, и страница для управления ей. Все это оформлено в HTML-формате и нам осталось только добавить некоторые стили к нашему новому шаблону.
Условная проверка перед подключением CSS
Чтобы подгрузить таблицы стилей, приведенные ниже, только к нашему кастомному шаблону (template-team.php), мы можем использовать следующую условную проверку:
/**
* Подгрузка таблиц CSS для template-team.php
*/
function team_styles() {
if ( is_page_template('template-team.php') )
wp_enqueue_style( 'team-template', get_stylesheet_directory_uri() . '/assets/css/team.css' );
}
add_action( 'wp_enqueue_scripts', 'team_styles', 101 );
Этот кусок кода загрузит CSS-файл (/assets/css/team.css) только когда используется страница template-team.php. Использование этого метода поможет вам сохранить основные таблицы стилей нетронутыми.
Примеры таблиц стилей
Ниже представлены таблицы стилей, которые я использовал для примера в этой статье:
/* ==============================================
Team profiles
============================================== */
.profiles {
margin-bottom: -20px;
}
.intro {
padding-left: 140px;
}
.intro h2 {
margin: 0 0 7px;
}
.intro .lead {
line-height: 120%;
font-size: 1.1em;
font-style: italic;
margin: 0 0 35px;
}
.profile {
position: relative;
margin: 0 0 20px;
}
.profile:nth-child(even) {
clear: left;
}
.profile-header {
position: absolute;
top: 0;
}
.profile-header img {
float: left;
}
.profile-content {
font-size: 14px;
padding: 27px 20px 0 0;
line-height: 1.4em;
margin: 0 0 0 125px;
}
.profile-content h3 {
margin: 0;
}
.profile-content .lead {
font-size: 1.3em;
line-height: 100%;
font-style: italic;
margin: 3px 0 20px;
}
.profile-content:before {
content: '';
width: 36px;
height: 3px;
background: #dededc;
position: absolute;
top: 0;
}
.profile-content p {
margin: 0 0 10px;
}
.profile-footer {
position: absolute;
top: 121px;
width: 100px;
text-align: center;
}
.profile-footer a {
line-height: 18px;
margin: 0 3px;
display: inline-block;
}
.profile-footer a:hover i {
color: #595959;
}
.profile-footer a:active i {
color: #000;
}
.profile-footer i {
font-size: 18px;
position: relative;
}
.profile-footer i.icon-envelope {
font-size: 16px;
top: -1px;
}
.profile-footer i.icon-linkedin {
font-size: 16px;
top: -1px;
}
Для написания CSS-стилей я использовал текстовый препроцессор LESS. Ниже представлены те же стили, но записанные в формате препроцессора LESS:
/* ==================================================
Team profiles
================================================== */
// Mixins
.border-radius(@radius) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
// Global
.profiles {
margin-bottom: -20px; // Offset adjustment
}
.intro {
padding-left: 140px;
h2 {
margin: 0 0 7px;
}
.lead {
line-height: 120%;
font-size: 1.1em;
font-style: italic;
margin: 0 0 35px;
}
}
.profile {
position: relative;
margin: 0 0 20px;
&:nth-child(even) {
clear: left;
}
}
// Header
.profile-header {
position: absolute;
top: 0;
img {
float: left;
}
}
// Content
.profile-content {
font-size: 14px;
padding: 27px 20px 0 0;
line-height: 1.4em;
margin: 0 0 0 125px;
h3 {
margin: 0;
}
.lead {
font-size: 1.3em;
line-height: 100%;
font-style: italic;
margin: 3px 0 20px;
}
// Top separator
&:before {
content: '';
width: 36px;
height: 3px;
background: #dededc;
position: absolute;
top: 0;
}
p {
margin: 0 0 10px;
}
}
// Footer
.profile-footer {
position: absolute;
top: 121px;
width: 100px;
text-align: center;
a {
line-height: 18px;
margin: 0 3px;
display: inline-block;
}
a:hover i { color: #595959; }
a:active i { color: #000; }
i {
font-size: 18px;
position: relative;
}
i.icon-envelope {
font-size: 16px;
top: -1px;
}
i.icon-linkedin {
font-size: 16px;
top: -1px;
}
}
Заключение
Благодарю за прочтение! Надеюсь, эта статья дала вам целостное представление о том, как создавать информацию о команде разработчиков и управлять ей в WordPress. Если вы поняли основополагающие концепции, изложенные выше, то, возможно, теперь имеете кардинально иной взгляд на способы управления настраиваемым контентом в WordPress.
Кастомные типы записей, таксономии и метабоксы предоставляют мощные средства для комплексного управления данными в WordPress.