Как создать дочернюю тему WordPress
Создайте дочернюю тему WordPress, чтобы сохранить изменения при обновлении родительской темы. Настройте классические блочные темы, стили и переопределение шаблонов.
Чтобы создать дочернюю тему WordPress, добавьте новую папку в wp-content/themes, поместите в неё файл style.css, у которого заголовок Template совпадает с именем папки родительской темы, и активируйте тему. Дочерняя тема наследует шаблоны, стили и функциональность родительской и содержит только ваши изменения.
Если вы когда-нибудь редактировали файлы темы напрямую, а затем видели, как очередное обновление их стирает, дочерняя тема решит эту проблему.
В этом руководстве описана настройка для современных версий WordPress. Мы разберём классическую дочернюю тему с правильным подключением стилей, переопределение шаблонов и функций, особенности блочных тем вроде Twenty Twenty-Four, а также случаи, когда дочерняя тема вообще не нужна.
Ключевые выводы
- Единственный обязательный файл дочерней темы —
style.css. Его заголовокTemplateдолжен в точности совпадать с именем папки родительской темы: для Twenty Twenty-Four этоtwentytwentyfour. - Файл
functions.phpдочерней темы не заменяет родительский. WordPress загружает оба, причём файл дочерней темы выполняется первым. - Подключайте стили дочерней темы через
wp_enqueue_style()на хукеwp_enqueue_scripts, а не через@import. - Чтобы переопределить шаблон, часть шаблона или паттерн, поместите в дочернюю тему файл с тем же именем. Для блочных паттернов также должен совпадать
Slug. - Изменения, которые должны сохраняться при смене темы (например, пользовательские типы записей), следует размещать в плагине, а не в дочерней теме.
Почему не стоит редактировать родительскую тему напрямую?
При обновлении темы WordPress заменяет её файлы новой версией, поэтому любые правки внутри папки темы теряются. Дочерняя тема хранит ваши изменения в отдельной папке, которую обновления не затрагивают. Раздел о дочерних темах в Theme Handbook описывает этот подход как способ получать обновления родительской темы, не отказываясь от собственных правок. Система тем ограничена двумя уровнями — родительским и дочерним, — поэтому установить «внучатую» тему поверх дочерней нельзя.
Как создать дочернюю тему в WordPress (классические темы)
Классической дочерней теме нужны папка, файл style.css с заголовком Template и, в большинстве случаев, файл functions.php, подключающий таблицу стилей. Структура такая же — папка, style.css и functions.php, — как описано в нашем руководстве по созданию адаптивной темы WordPress на Bootstrap. Разница в том, что дочерняя тема содержит только то, что она изменяет.
wp-content/themes/
├── twentytwentyfour/
└── tt4-child/
├── style.css
└── functions.php
Заголовок style.css
Строго обязателен только style.css. Согласно документации по основной таблице стилей, любой теме нужен как минимум заголовок Theme Name, а дочерняя тема дополнительно указывает Template.
/*
* Theme Name: TT4 Child
* Template: twentytwentyfour
* Version: 1.0.0
* Text Domain: tt4-child
*/
В Template указывается имя папки родительской темы, а не её отображаемое название. Если значения не совпадают посимвольно, WordPress не свяжет дочернюю тему с родительской.
Подключение стилей вместо @import
Подключайте стили дочерней темы через wp_enqueue_style() на хуке wp_enqueue_scripts, а не через @import. Во многих старых руководствах стили родительской темы загружаются с помощью @import в начале style.css дочерней темы. Этот подход устарел:
/* Outdated: do not use */
@import url("../twentytwentyfour/style.css");
Браузер обнаруживает импортируемый файл только после того, как загрузит и разберёт таблицу стилей дочерней темы, поэтому два запроса выполняются последовательно и оба блокируют отрисовку. Кроме того, импорт находится вне системы подключения ресурсов WordPress, а значит, WordPress не может управлять его зависимостями, версионированием и исключением дублей.
Вместо этого используйте wp_enqueue_style(), вызываемую из функции, привязанной к хуку wp_enqueue_scripts. Тот же хук используется и для подключения скриптов — об этом рассказывается в нашей статье о добавлении собственного JavaScript в темы WordPress.
<?php
// functions.php
add_action( 'wp_enqueue_scripts', 'tt4child_enqueue_styles' );
function tt4child_enqueue_styles() {
wp_enqueue_style(
'tt4child-style',
get_stylesheet_uri(), // the active (child) theme's style.css
array(), // $deps: handles that must load first
'1.0.0' // $ver: appended as a cache-busting query string
);
}
Правильный код подключения для дочерней темы зависит от того, что уже подключает родительская тема:
| Что подключает родительская тема | Что делает дочерняя тема |
|---|---|
| И собственную таблицу стилей, и таблицу дочерней темы | Ничего |
| Только собственную таблицу стилей | Подключает свою через get_stylesheet_uri() (код выше) |
Только таблицу активной темы через get_stylesheet_uri() | Подключает родительскую через get_parent_theme_file_uri( 'style.css' ) |
| Ничего (Twenty Twenty-Four, согласно Handbook) | Подключает свою через get_stylesheet_uri() |
Для третьей строки используйте такой код:
function tt4child_enqueue_styles() {
wp_enqueue_style(
'tt4child-parent-style',
get_parent_theme_file_uri( 'style.css' )
);
}
Чтобы определить, какой случай ваш, найдите wp_enqueue_style в functions.php родительской темы или поищите теги <link> для таблиц стилей в исходном коде страницы. Порядок таблиц стилей не фиксирован: он определяется вызовами подключения, а аргумент $deps принимает массив зарегистрированных дескрипторов (handles), которые должны загрузиться раньше. Чтобы стили дочерней темы выводились после родительских, передайте в $deps дескриптор родительской таблицы стилей, взяв его имя из кода родительской темы. Если URL таблицы стилей дочерней темы указан неверно, запрос вернёт 404, и страница отобразится только с CSS родительской темы. Запись сессии (session replay), которая фиксирует сетевые запросы параллельно с визуальным воспроизведением, покажет неудачный запрос рядом со страницей без стилей.
Как переопределить шаблоны родительской темы?
Чтобы переопределить шаблон родительской темы, скопируйте файл (а не переместите его) по тому же относительному пути в дочернюю тему. Проходя по иерархии шаблонов, WordPress проверяет папку дочерней темы раньше родительской, поэтому используется одноимённый файл из дочерней темы. Если переместить файл вместо копирования, вы измените родительскую тему, и при следующем обновлении файл всё равно вернётся на место.
twentytwentyfour/page.php → copy to → tt4-child/page.php
То же правило действует и для частей шаблонов. Можно также добавлять новые шаблоны, которых нет в родительской теме.
Переопределение функций родительской темы
Файл functions.php дочерней темы не заменяет родительский. Согласно Handbook, WordPress выполняет оба файла: сначала дочерний, а сразу за ним — родительский. Из такого порядка загрузки следуют два вывода. Функции родительской темы, обёрнутые в function_exists() (так называемые pluggable-функции), можно переопределить в дочерней теме. Любую другую функцию родительской темы придётся отвязать от хука или дополнить. Также не копируйте код из functions.php родительской темы в дочернюю: повторное объявление функций с теми же именами приведёт к фатальной ошибке и остановит сайт.
Pluggable-функция в родительской теме выглядит так:
// Parent theme
if ( ! function_exists( 'parenttheme_credit' ) ) {
function parenttheme_credit() { /* ... */ }
}
Поскольку дочерняя тема выполняется первой, определение функции с тем же именем в ней приводит к тому, что родительская версия пропускается:
// Child theme
function parenttheme_credit() {
echo '<p>Custom credit line</p>';
}
Если функция не является pluggable, удалите её с помощью remove_action(), указав тот же хук и приоритет, с которыми она была зарегистрирована. Вызов remove_action(), размещённый на верхнем уровне файла дочерней темы, выполнится до того, как родительская тема добавит свой хук, — удалять будет ещё нечего. Выполняйте его на хуке after_setup_theme, который срабатывает после загрузки файлов functions.php обеих тем:
// Parent theme
add_action( 'init', 'parenttheme_setup_extra', 20 );
// Child theme
add_action( 'after_setup_theme', function () {
remove_action( 'init', 'parenttheme_setup_extra', 20 );
} );
Для фильтров аналогично работает remove_filter(). Чтобы дополнить функцию родительской темы, а не заменить её, привяжите собственную функцию к тому же хуку с более поздним приоритетом. Приоритет по умолчанию для add_action() равен 10, и чем больше число, тем позже выполняется функция:
add_action( 'parent_footer', 'tt4child_footer_extra', 20 );
Как работают дочерние темы для блочных тем?
Дочерней теме для блочной темы, например на основе Twenty Twenty-Four, зачастую достаточно файлов style.css и theme.json. Стили в основном задаются в theme.json, поэтому, как отмечает Handbook, подключать style.css часто не требуется, и у многих блочных дочерних тем вообще нет functions.php.
| Классическая дочерняя тема | Блочная дочерняя тема | |
|---|---|---|
| Обязательный файл | style.css | style.css |
| Где задаются стили | style.css (подключается) | theme.json |
functions.php | Обычно есть, для подключения стилей | Часто отсутствует |
| Шаблоны | Файлы .php в корне темы | Файлы .html в templates/ |
| Части шаблонов | Файлы .php, например header.php | Файлы .html в parts/ |
| Паттерны | PHP-файлы в patterns/ или register_block_pattern() | PHP-файлы в patterns/ |
tt4-child/
├── style.css
├── theme.json
├── templates/
│ └── single.html
├── parts/
│ └── header.html
└── patterns/
└── (same filename as the parent pattern).php
Чтобы переопределить шаблон, часть шаблона или паттерн, добавьте файл с тем же именем. Для паттернов зарегистрированный заголовок Slug также должен совпадать с родительским, поэтому скопируйте его из файла родительской темы:
<?php
/**
* Title: Footer
* Slug: parent-slug/pattern-name
*/
?>
Минимальный theme.json фиксирует схему и использует версию 3, для которой требуется WordPress 6.6 или новее:
{
"$schema": "https://schemas.wp.org/wp/6.6/theme.json",
"version": 3,
"styles": {
"typography": {
"lineHeight": "1.7"
}
}
}
Файлы theme.json родительской и дочерней темы объединяются по определённым правилам слияния, при этом значения дочерней темы имеют приоритет. Изменения, сохранённые в редакторе сайта (Site Editor), хранятся в базе данных и в многоуровневой модели Handbook располагаются над дочерней темой. Если кажется, что шаблон дочерней темы игнорируется, сбросьте сохранённые изменения этого шаблона в редакторе сайта.
Когда дочерняя тема не нужна
Для небольших визуальных правок или функциональных возможностей дочерняя тема не нужна. В классической теме для нескольких правил достаточно раздела «Дополнительные стили» (Additional CSS) в Настройщике (Customizer). Если активна блочная тема, пользовательский CSS добавляется через панель «Стили» в редакторе сайта. Функциональные изменения, например пользовательские типы записей, следует выносить в плагин, чтобы они продолжали работать после смены темы. Если изменений становится так много, что дочерней темой трудно управлять, Handbook рекомендует сделать форк родительской темы и превратить его в собственную тему.
Заключение
Дочерняя тема сводится к одной папке и файлу style.css, значение Template в котором совпадает с именем папки родительской темы. Для классических тем добавьте код подключения стилей, соответствующий тому, что загружает родительская тема. В блочных темах основную работу выполняют theme.json и одноимённые файлы шаблонов. Начните с проверки того, какие таблицы стилей подключает ваша родительская тема, а затем добавляйте только те файлы, которые действительно нужно изменить.
Часто задаваемые вопросы
В чём разница между get_template_directory_uri() и get_stylesheet_directory_uri() в дочерней теме?
Когда активна дочерняя тема, get_template_directory_uri() возвращает URL каталога родительской темы, а get_stylesheet_directory_uri() — URL каталога дочерней темы. Для файлов, хранящихся в дочерней теме, используйте вариант со stylesheet. Начиная с WordPress 4.7 зачастую лучше использовать get_theme_file_uri(): эта функция возвращает копию файла из дочерней темы, если она существует, а в противном случае — файл родительской темы.
Почему после активации дочерней темы пропали настройки Настройщика и области меню?
WordPress хранит настройки Настройщика (theme mods) отдельно для каждой темы, привязывая их к имени папки активной темы, поэтому дочерняя тема начинает с собственного пустого набора и не наследует настройки родительской. Ваши меню по-прежнему существуют, но их нужно заново назначить областям меню, а остальные настройки — ввести повторно или импортировать. Настройки родительской темы остаются в базе данных и вернутся, если вы снова переключитесь на неё.
Что происходит с файлом шаблона, скопированным в дочернюю тему, при обновлении родительской темы?
Копия в дочерней теме остаётся именно такой, какой вы её сохранили, и WordPress продолжает использовать её вместо обновлённого файла родительской темы. Исправления ошибок, патчи безопасности и изменения разметки, которые родительская тема вносит в этот файл, до вашего переопределения не доходят. После каждого обновления родительской темы сравнивайте переопределённые файлы с новыми версиями и переносите нужные изменения. Чтобы это оставалось посильной задачей, переопределяйте как можно меньше файлов.
Можно ли создать дочернюю тему для блочной темы без написания кода?
Да. В официальном плагине Create Block Theme на WordPress.org есть функция Create Child Theme. Она создаёт дочернюю тему для активной блочной темы, например Twenty Twenty-Four, и записывает изменения, сделанные в редакторе сайта, в файлы дочерней темы. Плагин предназначен для блочных тем, поэтому для дочерней темы классической родительской по-прежнему потребуется описанная выше настройка style.css и functions.php.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k