Создание кастомного типа записи Event в WordPress
Одно из ключевых преимуществ WordPress — гибкость. Платформа подходит не только для записей и страниц: кастомные типы записей позволяют расширить базовый функционал почти до любой структуры контента.
В этой статье мы разберём, зачем нужны кастомные типы записей, как создать тип “Event” для публикации мероприятий и как вывести список событий в архиве с правильной датой и сортировкой.
Что такое кастомные типы записей
Обычно сайт на WordPress состоит из двух типов контента: блога (дата) и статичных страниц. Кастомные типы записей (custom post types, CPT) — это способ добавить ещё один вид контента, который не попадает в хронологический поток блога и имеет собственную логику и интерфейс в админке.
Пример: для клуба удобно иметь раздел «События». Использовать обычные посты неудобно — они будут смешиваться с записями блога. Кастомный тип записи позволяет отделить события и показать их в отдельном архиве, меню и шаблонах.
Когда использовать CPT и когда плагин
Важно: если вам нужна готовая и надёжная система мероприятий с календарём, повторяющимися событиями и продажей билетов — используйте специализированный плагин, например The Events Calendar. Если же ваша цель — изучение или лёгкая интеграция в тему, CPT руками — хороший вариант.
Плагины и инструменты для создания CPT:
- The Events Calendar — полный функционал для событий.
- Custom Post Type UI (CPT UI) — быстро регистрирует CPT без кода.
- Advanced Custom Fields (ACF) — удобные метаполя.
- My Custom Functions — вставка фрагментов PHP без редактирования темы.
Как зарегистрировать тип записи Event (шаг за шагом)
Мы регистрируем тип записи в файле темы functions.php или в небольшом плагине. Лучше пользоваться дочерней темой или плагином, чтобы обновления темы не удалили изменения.
Откройте файл темы functions.php (wp-content/themes/ваша-тема/functions.php) и добавьте в конец файл следующий код:
add_action('init', 'events_init');
function events_init() {
$args = array(
'labels' => array(
'name' => __('Events'),
'singular_name' => __('Event'),
),
'public' => true,
'has_archive' => true,
'rewrite' => array("slug" => "events"),
'supports' => array('thumbnail','editor','title','custom-fields')
);
register_post_type( 'events' , $args );
}Примечания по коду:
- labels — подписи в интерфейсе. Для русификации замените (‘Events’) и (‘Event’) на русские строки или используйте функции локализации с текстовым доменом темы/плагина.
- public — делает тип видимым в админке и публичным на сайте.
- has_archive — включает автоматическую страницу-архив по адресу /events/.
- rewrite => array(“slug” => “events”) — задаёт базовый сегмент URL.
- supports — перечисляет поддержку миниатюры, редактора, заголовка и пользовательских полей.
Важно: если в functions.php есть закрывающий тег , добавляйте код до закрывающего тега. Но рекомендуемый подход в современных темах — вообще не использовать закрывающий тег PHP, тогда вставка безопаснее.
Важно: после регистрации типа записи WordPress может возвращать 404 для новых ссылок. Чтобы обновить структуру ссылок, зайдите в Настройки → Постоянные ссылки и нажмите «Сохранить изменения» (это вызовет flush_rewrite_rules). Для программного вызова при активации плагина используйте register_activation_hook и flush_rewrite_rules(false).
Пример кода для flush при активации (если вы упакуете регистрацию в плагин):
register_activation_hook( __FILE__, 'my_plugin_activation' );
function my_plugin_activation() {
// Регистрируем CPT (вызов функции регистрации тут или гарантируем, что она выполняется)
events_init();
// Обновляем правила пермалинков
flush_rewrite_rules(false);
}Добавление пользовательского поля «date» и формат хранения
В примере мы используем кастомное поле date для фактической даты события. В исходной заметке рекомендовался формат mm/dd/yyyy. Я рекомендую хранить дату в формате ISO YYYY-MM-DD или как Unix‑timestamp. Почему:
- Для сортировки по дате удобно использовать YYYY-MM-DD или timestamp.
- Формат mm/dd/yyyy плохо подходит для сравнения и сортировки.
Вы можете добавить поле вручную в мета-поле, использовать ACF для удобного UI или добавить metabox программно.
Пример простого метабокса для даты (упрощённо):
add_action('add_meta_boxes', 'events_add_meta_box');
function events_add_meta_box() {
add_meta_box('event_date', 'Дата события', 'events_date_meta_box_cb', 'events', 'side', 'default');
}
function events_date_meta_box_cb($post) {
$value = get_post_meta($post->ID, 'date', true);
echo '';
echo '';
}
add_action('save_post', 'events_save_meta_box_data');
function events_save_meta_box_data($post_id) {
if (array_key_exists('event_date_field', $_POST)) {
update_post_meta($post_id, 'date', sanitize_text_field($_POST['event_date_field']));
}
}Этот код рисует поле типа HTML5 date и сохраняет дату в метаполе ‘date’ в формате YYYY-MM-DD.
Настройка шаблона архива: archive-events.php
Поскольку мы указали has_archive => true, WordPress автоматически может показывать список по адресу /events/. Чтобы кастомизировать вывод для вашего типа записи, создайте в теме файл archive-events.php. WordPress использует шаблон archive-{post_type}.php автоматически.
Вы можете взять archive.php вашей темы и переименовать/cкопировать как archive-events.php. В оригинальной статье для Twenty Seventeen предлагалось заменить сложную вставку форматов постов на упрощённый блок. Вот типичный пример вывода записи в archive-events.php (упрощённый):
'.twentyseventeen_time_link().' ', '
' );?>Если вы вставляете этот код, обратите внимание, что он использует twentyseventeen_time_link() для вывода времени. Мы хотим вместо даты публикации показывать дату события из метаполя ‘date’. В исходном примере предлагалось заменить вызов на:
date('l jS F Y',strtotime(get_post_meta(get_the_ID(), 'date', true)))Однако для локализации предпочтительнее использовать date_i18n и формат даты из настроек сайта:
echo date_i18n( get_option('date_format'), strtotime( get_post_meta( get_the_ID(), 'date', true ) ) );Это отобразит дату события в формате, заданном в Настройки → Общие, и учтёт локализацию.
Добавьте несколько тестовых событий через админку и проверьте отображение.
После добавления событий создайте пользовательское поле date с реальной датой события. Если вы использовали HTML5 input type=”date”, админка сохранит YYYY-MM-DD.
Сортировка и вывод только будущих событий (WP_Query)
Часто нужно показывать в архиве только предстоящие события, отсортированные по дате. Пример WP_Query для вывода будущих событий, если дата хранится в формате YYYY-MM-DD:
$today = date('Y-m-d');
$args = array(
'post_type' => 'events',
'meta_key' => 'date',
'orderby' => 'meta_value',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'date',
'value' => $today,
'compare' => '>=',
'type' => 'DATE'
)
)
);
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) { $query->the_post();
// шаблон вывода записи
}
wp_reset_postdata();
}Если вы храните дату как timestamp, в meta_query используйте ‘type’ => ‘NUMERIC’ и сравнивайте с current_time(‘timestamp’).
Улучшения админки: колонки и сортировка по метаполю
Чтобы удобнее управлять событиями, добавьте в список записей колонки с датой события и сделайте её сортируемой.
Пример добавления колонки (упрощённо):
add_filter('manage_edit-events_columns', 'set_custom_edit_events_columns');
function set_custom_edit_events_columns($columns) {
$columns['event_date'] = 'Дата события';
return $columns;
}
add_action('manage_events_posts_custom_column' , 'custom_events_column', 10, 2);
function custom_events_column($column, $post_id) {
if ($column == 'event_date') {
echo esc_html( get_post_meta($post_id, 'date', true) );
}
}
add_filter('manage_edit-events_sortable_columns', 'events_sortable_columns');
function events_sortable_columns($columns) {
$columns['event_date'] = 'event_date';
return $columns;
}
add_action('pre_get_posts', 'events_column_orderby');
function events_column_orderby($query) {
if(!is_admin()) return;
$orderby = $query->get('orderby');
if('event_date' == $orderby) {
$query->set('meta_key', 'date');
$query->set('orderby', 'meta_value');
$query->set('meta_type', 'DATE');
}
}Альтернативные подходы и когда они применимы
- Встроенный CPT вручную в functions.php — подходит для разработчиков и сайтов со специфической логикой.
- CPT UI + ACF — быстрое решение без кода, удобно для контент‑менеджеров.
- Готовые плагины событий — нужны, если нужна встроенная логика календаря, повторов и тикетов.
Контрпример: если у вас одно‑разовое мероприятие на лендинге и вам не нужна архивация и фильтрация — обычная страница с блоком события может быть проще.
Безопасность и производительность
- Проверяйте и санитизируйте данные при сохранении (sanitize_text_field, intval, wp_kses_post для содержимого).
- Для больших объёмов событий храните дату в формате подходящем для индексации и используйте meta_query аккуратно: метаполя не индексируются так же хорошо, как колонки SQL, поэтому для масштабных проектов рассмотрите отдельную таблицу.
Чек-листы
Чек-лист для разработчика:
- Зарегистрирован CPT с корректными метками и capability_type при необходимости.
- Реализовано сохранение и валидация метаполя date.
- Обновлены шаблоны archive-events.php и single-events.php.
- Обработан flush_rewrite_rules на активации плагина или через сохранение пермалинков.
- Добавлены тесты или сценарии проверки вывода будущих/прошедших событий.
Чек-лист для администратора контента:
- Все события имеют корректное поле date в формате YYYY-MM-DD.
- У событий настроено изображение (миниатюра) и краткое описание, если требуется.
- Проверено отображение на мобильных устройствах.
Критерии приёмки
- Страница /events/ открывается и показывает архив событий.
- Каждая запись события показывает дату из метаполя, а не дату публикации.
- Сортировка по дате работает и по умолчанию показывает ближайшие будущие события.
- Перемещение темы/обновление не уничтожают функциональность (используется дочерняя тема или плагин).
Мини‑методология внедрения (шаги)
- Решите, где разместить регистрацию CPT (functions.php дочерней темы или плагин).
- Зарегистрируйте CPT и проверьте отображение в админке.
- Добавьте метаполе date и сохранение данных.
- Создайте archive-events.php и single-events.php.
- Настройте WP_Query для нужной сортировки/фильтрации.
- Протестируйте, добавьте улучшения админки и безопасность.
Совместимость и миграция
- При переносе на другой сайт экспортируйте CPT через инструменты экспорта WordPress или используйте WP Migrate DB. Если метаполя имеют иные имена — назначьте преобразование.
- Если вы используете ACF, экспортируйте JSON полей.
Краткое объявление для сайта (100–200 слов)
Добавили новый раздел «События». Теперь все мероприятия публикуются как отдельный тип записей Event: их удобно фильтровать, сортировать и отображать в едином архиве. Каждое событие имеет собственное поле «Дата», миниатюру и описание. Для удобства администраторов добавлены колонки с датами и возможность сортировки. Раздел отображается по адресу /events/.
Глоссарий (1‑строка)
- CPT — кастомный тип записи; расширение типов контента в WordPress.
- Metafield / post_meta — пользовательское поле, хранящее метаданные записи.
- Archive — страница со списком записей определённого типа.
Краткое резюме
- CPT дают гибкость структурирования контента.
- Для событий храните дату в формате YYYY-MM-DD или timestamp.
- Создайте archive-events.php для кастомного вывода архива.
- Для готовых функций используйте проверенные плагины (The Events Calendar, ACF).
Если хотите, могу подготовить минимальный плагин из приведённого кода (файл плагина с регистрацией CPT, метабоксом и flush_rewrite_rules), или адаптировать шаблон под вашу тему.
Краткие заметки:
Важно: используйте дочернюю тему или вынесите код в плагин, чтобы не потерять изменения при обновлении темы.
Примечание: для сложных требований по событиям (повторы, продажи билетов, интеграция с календарями) выбирайте специализированные плагины.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone