Оновлення теми не патчить окремі файли. Theme_Upgrader качає zip, розпаковує його в wp-content/upgrade, а далі install_package викликає clear_destination: тека теми видаляється повністю, і на її місце переїжджає розпакований пакет. Дописаний рядок у functions.php, новий шаблон, підправлений CSS: усе це живе всередині тієї теки і зникає разом з нею. Дочірня тема лежить в окремій теці з власним style.css, у заголовку якого вказано Template з іменем теки батьківської. Джерела оновлень у неї немає, оновлювач до неї не звертається, тому вона переживає будь-яку кількість оновлень оригіналу. З WP 5.5 теми оновлюються автоматично прямо з адмінки, і розрахунок «ми просто не тиснутимемо кнопку» більше не рятує.
Далі починається те, на чому валяться навіть ті, хто дочірню тему зробив. Її сила в тому, скільки файлів у ній немає. Кожен скопійований шаблон це форк: автор батьківської теми виправляє в ньому баг, додає атрибути доступності, змінює класи під новий CSS, а ваша копія лишається на версії дворічної давнини й тихо перебиває оновлений оригінал. Тому спершу шукайте точку розширення: add_filter на вивід, do_action всередині потрібного місця шаблону, get_template_part, який можна перекрити одним маленьким файлом. Копіювати шаблон варто тоді, коли хука справді немає, і копіювати цілком, а не «майже цілком».
Друга межа проходить між темою і плагіном. У дочірню тему йде оформлення; реєстрація типів записів, таксономій, шорткодів, інтеграцій і cron-задач їй не належить. Питання, яке все розставляє на місця: чи має сайт після переходу на іншу тему далі працювати з цими даними? Якщо так, код пишеться в site-specific плагін, а те, що взагалі не повинно вимикатись через адмінку, у wp-content/mu-plugins. Далі класика редизайну: увімкнули нову тему, і сотні записів типу portfolio пропали з меню, бо register_post_type жив у functions.php старої.
Дочірня тема захищає ваші файли, але не сумісність. Якщо автор перейменував content-single.php, прибрав do_action('theme_after_header') або переписав розмітку картки товару, ваше перекриття перестане спрацьовувати або почне рендерити стару структуру в новому CSS. Рятує тут процес, а не сама наявність дочірньої теми: @version у шапці скопійованих шаблонів (WooCommerce будує з них список outdated templates у розділі Статус), перевірка версії батьківської теми при оновленні, стейджинг, git на теку дочірньої теми та DISALLOW_FILE_EDIT у wp-config.php, щоб ніхто не правив файли повз репозиторій.
У блокових темах templates/*.html і parts/*.html перекриваються по імені файла, а theme.json дочірньої теми не замінює батьківський: WP_Theme_JSON_Resolver читає батьківський і мержить у нього дочірній по ключах, тому описувати треба лише відмінності. Окремий сюрприз для новачків: правки з Site Editor взагалі не лежать у файлах, вони зберігаються в базі як записи wp_template, wp_template_part і wp_global_styles. Оновлення теми їх не втратить, зате вони затінятимуть оновлені файли, і новий шаблон від автора не зʼявиться, поки користувач не зробить Clear customizations. Перекласти такі правки назад у файли дочірньої теми вміє плагін Create Block Theme.
// Правку робимо хуком, а не форком single.php батьківської теми:
// тоді оновлення батьківської не ламає ні розмітку, ні нашу вставку.
add_filter('the_content', function (string $content): string {
if (! is_singular('post') || ! in_the_loop() || ! is_main_query()) {
return $content;
}
ob_start();
get_template_part('parts/author', 'box'); // файл лежить у дочірній темі
return $content.ob_get_clean();
});
// Сторож для скопійованих шаблонів: дізнаємось про оновлення батьківської
// теми з логів, а не з поламаної сторінки.
add_action('admin_init', static function (): void {
$testedWith = '1.9';
$parentVersion = wp_get_theme(get_template())->get('Version');
if (version_compare($parentVersion, $testedWith, '>')) {
error_log("parent {$parentVersion} > tested {$testedWith}: звірити копії шаблонів");
}
});
// Копія шаблону виправдана там, де хука немає. У WooCommerce вона застаріває,
// тому версію оригіналу тримаємо в шапці файла:
// wp-content/themes/child/woocommerce/single-product/title.php
/**
* @version 3.0.0 <- звіряти з @version оригіналу; WooCommerce > Статус
* сам покаже список outdated templates
*/
// Реєстрація CPT, шорткоди й інтеграції живуть у плагіні, а не тут,
// бо зміна теми не повинна ховати контент.
// wp-config.php: правки йдуть через git, а не через редактор в адмінці
define('DISALLOW_FILE_EDIT', true);
Скажіть, що дочірня тема захищає файли, а не сумісність, і що головний ризик у ній - скопійовані шаблони. Сильна відповідь звучить так: мінімум копій, максимум хуків, а перевірка після оновлення батьківської теми входить у процес, а не робиться коли щось поламалось.