Создание пользовательского шаблона страницы

Файловая структура и базовый каркас шаблона
Пользовательский шаблон страницы реализуется через PHP-файл с обязательным идентификатором в первой строке. Файл размещается в корневой директории текущей активной темы или в её подпапке /page-templates/ — оба варианта валидны, но второй рекомендован кодексом WordPress для избежания путаницы с системными файлами. Минимальный каркас включает стандартный открывающий тег PHP и комментарий-маркер:
<?php /* Template Name: Моя кастомная страница */ ?>
После маркера следует стандартная разметка HTML5 с вызовом функций get_header(), get_footer() и основного цикла while ( have_posts() ) : the_post();. Отсутствие этого цикла делает шаблон непригодным для отображения контента, введённого в редакторе. Для корректной работы блочного редактора Gutenberg внутри цикла необходимо использовать the_content().
Материалы и типы файлов: что допустимо
Единственный разрешённый материал — PHP-файл с расширением .php. Использование чисто HTML- или CSS-страниц в качестве шаблона невозможно: WordPress не обрабатывает их как часть иерархии шаблонов. Альтернатива — размещение в дочерней теме, если основной код родительской темы не должен изменяться. В дочерней теме файл шаблона сохраняет такую же структуру, но ссылки на ассеты (CSS/JS) подключаются через wp_enqueue_style() и wp_enqueue_script() с использованием get_stylesheet_directory_uri() вместо get_template_directory_uri().
Спецификация заголовка и отличие от page.php
Ключевой элемент спецификации — строка «Template Name:». Пробел после двоеточия обязателен согласно синтаксису PHPDoc. Имя шаблона (в примере — «Моя кастомная страница») должно быть уникальным в пределах темы: дублирование названий вызывает в выпадающем списке выбора шаблона в админке запись с «(Duplicate)». В отличие от стандартного page.php, пользовательский шаблон даёт возможность полностью переопределить отображение: исключить сайдбар, изменить структуру контейнера, добавить произвольный набор полей через ACF. Стандартный page.php использует иерархию (page-{slug}.php, page-{id}.php), но его приоритет ниже явно назначенного пользовательского шаблона, что зафиксировано в ядре WordPress через хук template_include.
Приоритет загрузки и стандарты качества (WPCS)
WordPress загружает пользовательский шаблон, если: 1) в мета-боксе редактора выбран конкретный шаблон; 2) соблюдён приоритет: user_custom_template > page-{slug}.php > page-{id}.php > page.php > singular.php > index.php. Технически это реализовано в файле wp-includes/template.php через array_filter. Для соответствия стандартам кодирования WordPress (WPCS) необходимо: использовать пространства имён для функций, избегать прямого вызова $_GET/$_POST без nonce-проверки, оборачивать все строки перевода в __(), внедрять шаблоны только через include(locate_template()) для child-тем. Качество шаблона измеряется скоростью выполнения — не более 0.3 секунды генерации на странице с 5-ю запросами к БД — и полным отсутствием notice-level ошибок при включённом WP_DEBUG.
Технические нюансы: Conditional Tags и настройка запроса
Пользовательский шаблон может расширяться условными тегами (conditional tags) для логики отображения. Например, is_page_template('template-name.php') — единственный надёжный способ проверить, активен ли шаблон, внутри functions.php. Для подгрузки специфических стилей следует использовать хук wp_enqueue_scripts с проверкой:
if ( is_page_template( 'page-templates/about-custom.php' ) ) {
wp_enqueue_style( 'about-style' );
}
При необходимости изменить глобальный запрос WP_Query внутри шаблона (например, вывести другие записи вместо контента страницы), обязательно использовать wp_reset_postdata() после цикла — без этого последующие элементы темы потеряют корректный контекст поста. Оптимально создавать отдельный query с аргументами, отличными от основного $wp_query, для избежания side-effects на пагинацию.
Материалы: интеграция с ACF и Timber
Если шаблон использует произвольные поля через Advanced Custom Fields, поля необходимо зарегистрировать через acf_add_local_field_group() в functions.php, а внутри шаблона выводить через get_field(). При этом сам файл шаблона остаётся типовым PHP-файлом, без изменения структуры. Альтернатива — технический подход с Timber: шаблон создаётся как .twig-файл в подпапке /views/, а PHP-заглушка в /page-templates/ получает объект Timber\Post и передаёт данные через Timber::render(). Это требует установки плагина Timber, но даёт изоляцию логики от представления, что соответствует стандартам современной архитектуры MVC.
Сравнение с альтернативами: блоки темы и FSE
Создание пользовательского шаблона через PHP-файл — самый низкоуровневый и гибкий метод. Альтернатива — редактор полного сайта (Full Site Editing) с шаблонами в виде HTML-блоков внутри папки /wp-content/templates/ — там архитектура опирается на блоки и JSON-метаданные, но требует темы, поддерживающей FSE (например, Twenty Twenty-Four). Однако FSE-шаблоны не позволяют подключать произвольные PHP-функции напрямую, что ограничивает сложную логику. Ещё один вариант — плагины-конструкторы шаблонов (Elementor, Bricks): они создают запись в БД, а не файл на сервере, из-за чего производительность страдает на 15–30% (по тестам GTmetrix при числе блоков >40). Классический пользовательский шаблон остаётся эталоном по минимальному весу и полному контролю над разметкой.
Производственный процесс: от идеи до тестирования
- Создание PHP-файла с именем, соответствующим шаблону (без кириллицы и пробелов, латиница и дефис).
- Добавление заголовка Template Name в первой строке.
- Подключение get_header() и get_footer() с проверкой на активные виджеты через is_active_sidebar().
- Реализация цикла с проверкой наличия записей (if ( have_posts() )).
- Внедрение wp_reset_postdata() после завершения цикла.
- Подключение CSS/JS через wp_enqueue_style/wp_enqueue_script с условной проверкой is_page_template.
- Тестирование на сервере с версией PHP 8.1+ и WordPress 6.6+ без плагинов кэширования.
- Валидация ошибок через инструменты Query Monitor: время генерации, количество SQL-запросов, наличие deprecated функций.
На этапе тестирования обязательна проверка в режиме отладки (define('WP_DEBUG', true)) — любой Notice уровня E_NOTICE считается несоответствием стандартам качества.
Материалы для исключения конфликтов
- Правильные пути: для подключения файлов из темы использовать get_template_directory() или get_stylesheet_directory() — не хардкодить URL.
- Защита от прямого доступа: в начале файла добавить проверку defined('ABSPATH') or die; — это блокирует исполнение при прямом обращении по URL.
- Отсутствие глобального $post: внутри шаблона не полагаться на $post без предварительной настройки через setup_postdata().
- Параметр post_type: если шаблон используется для произвольного типа записи, удостовериться, что в заголовке Template Name не пропущена поддержка этого типа через add_theme_support( 'page-templates', 'my_cpt' ).
Только при соблюдении этих технических условий пользовательский шаблон страницы работает без сбоев и полностью совместим с ядром WordPress версии 6.6 и выше, что подтверждается официальным суппортом WPCS.
Добавлено: 24.04.2026
