Дочерние темы — для чего нужны и как с ними работать

И сразу же постараюсь ответить на вопрос из заголовка — для чего нужны дочерние темы?

  • Если вам когда-нибудь приходилось редактировать темы сторонних разработчиков, то вы наверняка в курсе, что после обновления темы, все сделанные изменения в файлах исчезают. Конечно, вы можете просто отключить возможность обновления тем, но использование дочерних шаблонов — более правильный вариант.
  • Также родительскую тему можно использовать как общий шаблон для многих сайтов. Всё равно у каждого разработчика есть какой-то код, который он использует для всех своих сайтов, например некоторые хуки. Получается, что использование дочерних тем, позволяет сэкономить время.

Как создать дочернюю тему?

В качестве примера давайте возьмём стандартную тему WordPress Twenty Twelve — для неё и создадим дочернюю тему.

  1. Первым шагом создаем директорию дочерней темы:
    Директория дочерней темы

    Я назвал её twentytwelve-child, но это совсем не обязательно — можете называть как угодно, главное, чтобы название темы не содержало пробелов и русских букв.

  2. Следующим шагом — работа со style.css. У меня он начинается с этого:
    /*
     Theme Name:   Twenty Twelve Child
     Author:       Misha Rudrastyh
     Author URI:   https://truemisha.ru
     Template:     twentytwelve
    */

    Самым важным в данном случае является параметр Template — он и определяет то, что эта тема дочерняя. Параметр содержит название директории родительской темы.

  3. На этом этапе дочерняя тема появится в админке вашего сайта.
    Дочерняя тема в админке сайта

    Если вы активируете её и перейдёте на сайт, то заметите, что вместо таблицы стилей родительской темы подгружается таблица стилей дочерней темы. Если именно это вам и нужно, то можете пропустить следующий шаг.

  4. Создаём в папке с дочерней темой functions.php и добавляет туда хук, который будет подключать таблицу стилей родительской темы на сайт и сразу же за ней — таблицу стилей дочерней темы.
    function true_enqueue_styles() {
    	wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
    	wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array('parent-style') );
    }
     
    add_action( 'wp_enqueue_scripts', 'true_enqueue_styles' );

    Как результат — на вашем сайте сейчас будет точная копия родительской темы.

  5. Также иногда бывает нужно пересохранить меню Внешний вид > Меню и настройки темы.

Как работают дочерние темы?

На самом деле всё очень и очень просто — файлы, которые вы создаёте в директории дочерней темы, будут заменять эквивалентные им файлы из родительской темы.

style.css и functions.php

Исключение составляют эти два файла.

  • Если вы задействовали у себя хук, о котором я писал чуть выше, то файл дочерняя таблица стилей будет загружаться в дополнение к таблице стилей родительской темы.
  • functions.php дочерней темы всегда подключается непосредственно перед functions.php родительской темы. Что делать, если нужно задействовать функцию после инициализации functions.php родительской? Используйте хук after_setup_theme с приоритетом больше 10.

Функции

Родительская тема Дочерняя тема
get_template_directory_uri() — возвращает URL родительского шаблона. get_stylesheet_directory_uri() — возвращает URL текущего шаблона (т е, если функция используется в дочерней теме, то выведен будет URL дочерней темы).
get_template_directory() — возвращает абсолютный путь к директории родительской темы на сервере. get_stylesheet_directory() — возвращает абсолютный путь к директории текущей темы на сервере.

Локализация

Процесс перевода дочерних тем по сути ничем не отличается от локализации недочерних тем. Про локализацию читайте подробнее здесь.

Подпишитесь, чтобы раз в неделю получать свежие статьи с блога по email.

Смотрите также

Комментарии 32

  • weber27 февраля 2015 в 18:02 #

    Дочерние темы отличный выхход из таких ситуаций когда кастомишь тему а она потом слетает. Хотя есть и другие варианты для такого случая.

  • Анастасия28 февраля 2015 в 08:02 #

    Люблю работать с дочерними темами =) В любом случае, так безопаснее исходную тему менять и обновления основной более-менее нормально проходят. А то в основном жалуются, что что-то изменил и сайт полетел

  • Виталик9 марта 2015 в 15:03 #

    Миша, подскажи пожалуйста, под постом (wifika.ru/a-chem-vyi-zaymetes-v-prazdniki.html ,сайт не мой, но шаблон такой же) выводятся соц.сети и как вместо Pinteresta поставить ссылку Вконтакте (поделиться) со счетчиком. Тяжело ли это сделать? Помоги пожалуйста!
    p.s. если нужно заплатить, скажи сколько это будет стоить примерно?

    • Миша10 марта 2015 в 07:03 #

      Ну, если нужно сделать точно такого же стиля, то там конечно придется поколдовать. Пиши мне на email, могу помочь с этим.

  • Александр28 апреля 2015 в 23:04 #

    подскажите пожалуйста где и как найти родительскую тему где она находится?? мне нужно в ней поменять чтобы текст на сайте был на всю страницу а у меня он посередине с боков много пустого места

    • Миша29 апреля 2015 в 09:04 #

      Папка родительском темы совпадает со значением Template: twentytwelve в файле style.css дочерней темы.

  • Егор26 октября 2015 в 02:10 #

    Здравствуйте. Миша, не сталкивались с таким? Дочернюю тему устанавливаю, все как всегда, стили подгружаются, но вот при публикации постов, нажимаешь публиковать, появляется белый экран, обновляешь браузер, все норм. Аналогично - при установке или удаленни плагинов, страниц и прочего.

  • Егор26 октября 2015 в 08:10 #

    Попробую попозже. Сейчас времени нет :) Я даже и не подумал. Действительно. Там тема эта sahifa, арабы понамутили. Вообще должны уже готовую заготовку для дочерки в архиве поставлять.

  • Егор15 ноября 2015 в 07:11 #

    Здравствуй, Миша. А как лучше подключать? Как у тебя в статье, или через @import ? Через @import файл стилей дочерней темы полностью заменяет родительский и родительский уже не подключается родительский style. В варианте с хуком дочерний файл дополняет родительские стили и подкл. оба файла.

  • Максим15 января 2016 в 16:01 #

    Здраствуйте! А вы не подскажите как сделать так чтоб для мобильной версии стили дочерней не подключались? Подключены они через @import, по другому не вышло. Заранее спасибо!

    • Миша16 января 2016 в 07:01 #

      Здравствуйте, а через media queries не прокатывает?

      • Максим16 января 2016 в 18:01 #

        Тоесть примерно так? @media screen and (max-width: ..)
        Я так подключил. Но выходит какойто баг. Стили через @media screen перебивают некоторые стили в теме при полном экране. Я сначала грешил на !important, но нет. Вот я и думаю, может как то можно сделать чтоб стили там одни а там другие.

  • Андрей1 апреля 2016 в 23:04 #

    Добрый день! Вопрос по поводу дочерней темы WordPress. Попытка создания по схеме, которая описана у Вас в блоге увенчалась лишь частичным успехом: не все оформление меню корректно отображается на странице. Тема называется llorix-one-lite.

    Код файлов дочерней темы:
    functions.php

    function true_enqueue_styles() {
    wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array('parent-style') );
    }
     
    add_action( 'wp_enqueue_scripts', 'true_enqueue_styles' );

    style.css

    /*
    Theme Name: lol
    Author: AAK
    Author URI:
    Template: llorix-one-lite
    */
    @import url('../llorix-one-lite/style.css'); /*Пробовал с и без*/

    Без последней строчки работает криво во всех бразуерах, с последней строчкой только в Chrome проблема (в IE 11 и Fierfox отображается нормально). Либо javascripts не подгружается либо CSS не весь: фон заголовка окрашивается темно-синим цветом, с черными буквами меню и все сливается, хотя в главной теме цвет фона белый!

    Кривое отображение: https://yadi.sk/i/xqEjGP7VqfqDb
    Нормальное отображение: https://yadi.sk/i/bQfUQm0JqfqGp

    Спасибо!

    • Миша1 апреля 2016 в 23:04 #

      Добрый день,
      так, у меня два вопроса:

      1. Задача дочерней темы это подключение файла стилей и всё?
      2. До создания дочерней темы всё 100% работало как надо (даже без проблемы в Chrome) ?
  • Андрей1 апреля 2016 в 23:04 #

    1. Задача дочерней темы, на данном этапе подключение стилей и все. Как только дочерняя тема начнет корректно работать, я перейду к следующему этапу: добавление нового кода и новых стилей. Но пока мне нужно сделать так, чтобы дочерняя тема начала правильно отображаться.

    2. Не работает именно дочерняя тема, родительская тема работает хорошо, это видно из скриншотов.

    • Миша1 апреля 2016 в 23:04 #

      Ок, ясно, а код из дочерней темы работает корректно? Пробовали его просто в конец style.css родительской темы вставить?

      • Андрей1 апреля 2016 в 23:04 #

        Пробовал вместо почти "пустого" файла style.css дочерней темы помещать копию файла родительской темы. Не помогло.
        Сейчас попробовал добавит код в конец style.css. Не помогло.

        • Миша1 апреля 2016 в 23:04 #

          Смотрите, без доступа к сайту конечно трудно что-то сказать, но у меня есть два предположения — либо в ваших стилях, которые вы добавляете, что-то не совсем то, либо ваши стили вставляются ДО стилей родительской темы, и склоняюсь я ко второму варианту.

          Можете сделать Ctrl + U и скинуть ссылку на скриншот всего кода сайта после подключения дочерней темы?

  • Андрей2 апреля 2016 в 19:04 #

    Большое спасибо, Михаил, очень помогли!

    Тема работает, но я не совсем понял, как вы ее исправили. Вот то, что я вытащил из functions.php родительской темы:

    wp_enqueue_style( 'llorix_one_lite_admin_stylesheet', llorix_one_lite_get_file('/css/admin-style.css'),'1.0.0' );
    wp_enqueue_style( 'llorix-one-lite-fontawesome', llorix_one_lite_get_file( '/css/font-awesome.min.css' ),array(), '4.4.0');
     
    wp_enqueue_style( 'llorix-one-lite-bootstrap-style', llorix_one_lite_get_file( '/css/bootstrap.min.css'),array(), '3.3.1');
    wp_enqueue_style( 'llorix-one-lite-style', get_stylesheet_uri(), array('llorix-one-lite-bootstrap-style'),'1.0.0');

    вот то что было в начале, и что не работало:

    wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' ); 
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array('parent-style') );

    вот, что сделали вы:

    wp_enqueue_style( 'llorix-one-lite-style', get_template_directory_uri() . '/style.css', array('llorix-one-lite-bootstrap-style') );
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array('llorix-one-lite-style') );

    Насколько я понимаю вы подключили в начале bootstrap стили, затем... запутался ))

    в первой строке: parent-style -> llorix-one-lite-style и добавили array('llorix-one-lite-bootstrap-style')

    во второй строке: parent-style -> llorix-one-lite-style и array('parent-style') -> array('llorix-one-lite-style')

    parent-style - это переменная, название ее можно было не менять, насколько я понимаю?
    $handle(строка) (обязательный)Название файла стилей (идентификатор). Строка в нижнем регистре. Если строка содержит знак вопроса (?): scriptaculous?v=1.2, то предшествующая часть будет названием скрипта, а все что после будет добавлено в УРЛ как параметры запроса. Так можно указывать версию подключаемого скрипта.

    можно было бы оставить так?

    wp_enqueue_style( 'parent-style ', get_template_directory_uri() . '/style.css', array('llorix-one-lite-bootstrap-style') );
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array('parent-style ') );

    и почему style.css остался прежним, bootstrap подключается в funcrtions как bootstrap.min.css?

    • Миша3 апреля 2016 в 07:04 #

      Итак, задача нашей дочерней темы заключалась в том, чтобы подключить свой style.css после style.css родительской темы, сохранив при этом порядок стилей.

      В WordPress у каждого CSS и JS есть свой идентификатор, из родительской темы нас интересует только style.css, который llorix-one-lite-style и llorix-one-lite-bootstrap-style. Запомним их.

      Функция get_stylesheet_uri() возвращает URL файла style.css текущей темы, будь она родительской или дочерней — не важно, именно поэтому лишь при активации пустой дочерней темы с пустым style.css, сайт уже останется без основных стилей.

      CSS с ID llorix-one-lite-style будет подключаться в любом случае, именно поэтому его лучше переопределить, что я и сделал. Я сделал так, чтобы этот CSS всегда был файлом из родителькой темы.

      wp_enqueue_style( 'llorix-one-lite-style', get_template_directory_uri() . '/style.css', array('llorix-one-lite-bootstrap-style') );

      Ну а потом просто подключил CSS дочерней темы с завивимостью от родительского.

      wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array('llorix-one-lite-style') );
      • Андрей3 апреля 2016 в 11:04 #

        Не совсем понятно, Михаил. Кроме первого и последнего абзаца, непонятно.
        Добавляем стиль родительской темы:
        wp_enqueue_style( 'llorix-one-lite-style', можно назвать parent-style? или нельзя поскольку мы переопределяем handle именно с этим значением?
        get_template_directory_uri() . получаем путь родительской темы
        '/style.css', добавляем файл style.css
        array('llorix-one-lite-bootstrap-style') добавляем handle родительской темы для переопределения
        );
        Почем CSS с ID llorix-one-lite-style будет подключаться в любом случае? Почему если он будет подключаться в любом случае и при условии, что "style.css, который llorix-one-lite-style И llorix-one-lite-bootstrap-style" llorix-one-lite-style не тянет за собой llorix-one-lite-bootstrap-style?

        • Миша4 апреля 2016 в 07:04 #

          Окей, по порядку.

          Во-первых, в родительской теме есть определённый набор стилей, которые подключаются в определённом порядке. У каждого файла стилей есть свой ID, например llorix-one-lite-style. Эти стили будут подключаться в любом случае, потому что они прописаны в functions.php родительском темы. Можно их выковырять разными способами, но в данном случае ни к чему.

          Во-вторых, как только появляется дочерняя тема, то основной файл стилей llorix-one-lite-style уже берётся не из родительской, а из дочерней директории, потому что так работает функция (ссылка в предыдущем комментарии).

          В-третьих, нафига нужно llorix-one-lite-style называть parent-style? Дело в том, что llorix-one-lite-style подключится через родителький functions.php и у нас в итоге будет три файлы стилей, поэтому мы просто переопределим его, да попробуйте в конце концов и посмотрите исходный код, ничего же не случится, если вы попробуете, просто запомните, какой вариант правильный.

          Ну не знаю, как ещё понятнее объяснить :)

  • Андрей3 апреля 2016 в 14:04 #

    Михаил, еще вопрос! Пытаюсь добавить в дочерней теме код в функцию llorix_one_lite_customize_register(). Код должен добавлять в кастомизатор темы новую секцию и чекбокс, который будет скрывать или проявлять header. Если добавить код напрямую в родительскую тему в файл customizer.php, то все работает, но если добавить код в functions.php ничего не работает. Вот добавление кода через хук в functions.php дочерней темы (код который не работает):

    function my_customizer() {
    	// Добавляем собственную секцию настроек
    	$wp_customize->add_section(
    		'control_header', // id секции, должен прописываться во всех настройках, которые в неё попадают
    		array(
    			'title'     => 'Настройка header',
    			'priority'  => 200, // приоритет расположения относительно других секций
    			'description' => 'Настройте внешний вид вашего сайта' // описание не обязательное
    		)
    	);
     
    	// Отображение шапки
    	$wp_customize->add_setting(
    		'control_header_bool', // id
    		array(
    			'default'    =>  'true', // значение по умолчанию
    			'transport'  =>  $true_transport
    		)
    	);
    	$wp_customize->add_control(
    		'control_header_bool', // id
    		array(
    			'section'   => 'control_header', // название секции
    			'label'     => 'Отображать header?', // название настройки
    			'type'      => 'checkbox' // тип - чекбокс
    		)
    	);	
     
    }
     
    add_action( 'llorix_one_lite_customize_register', 'my_customizer' );
  • Андрей3 апреля 2016 в 14:04 #

    последний вопрос больше не актуален. Оказалось что нужно было делать так:

    /**
     * Добавление индивидуальный секций, опций и элементов управления к настройщику тем 
     */
    function example_customizer( $wp_customize ) {
        $wp_customize->add_section(
            'example_section_one',
            array(
                'title' => 'Пример настроек',
                'description' => 'Это секция настроек.',
                'priority' => 35,
            )
        );
    }
    add_action( 'customize_register', 'example_customizer' );
  • Андрей3 апреля 2016 в 17:04 #

    Михаил, еще раз побеспокою ))

    оказалось что не все стили подключились, как подключить оставшиеся:

    wp_enqueue_style( 'llorix_one_lite_admin_stylesheet', llorix_one_lite_get_file('/css/admin-style.css'),'1.0.0' );
    wp_enqueue_style( 'llorix-one-lite-fontawesome', llorix_one_lite_get_file( '/css/font-awesome.min.css' ),array(), '4.4.0');
     
    wp_enqueue_style( 'llorix-one-lite-style', get_stylesheet_uri(), array('llorix-one-lite-bootstrap-style'),'1.0.0');
  • Андрей15 апреля 2016 в 11:04 #

    Михаил, добрый день!

    Вопрос по поводу передачи параметров wp.customizer в переменную javascript (jQuery). Интересует передача значений булевой переменной. Была мысль добавить стиль пустышку в html при взведенной переменной. jQuery будет проверять наличие стиля и если находит этот стиль, то выставляет значение свой переменной в True. Думаю это корявый вариант и хотелось сделать более гамотно. Как это можно грамотно организовать не добавляя "мусорные" стили в html страницу? Может быть Json?

    • Миша15 апреля 2016 в 20:04 #

      Добрый день!
      Чтобы не добвлять мусорные стили, можно же просто класс добавить тому же <body>?

  • Андрей15 апреля 2016 в 20:04 #

    я видимо не так выразился, я это и имел ввиду... хотелось бы от этого избавиться, поскольку, что-нибудь потяжелее булевой переменной так передавать проблематично, да и плодить классы только для передачи переменных... хорошо если таких переменных одна - две... а если передать нужно массив...?

    • Миша16 апреля 2016 в 07:04 #

      К сожалению мне придётся ответить, что с этим не приходилось сталкиваться самому. Я бы разобрался, что к чему более детально, но время не позволяет.

      Но как только решение появится, я оставлю его в комментариях к этому посту.

Оставить комментарий / вопрос

phpjsHTMLCSSSQLПросто код
  Для того, чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или авторизуйтесь на сайте.
Получайте новости блога по email или следите за мной в социальных сетях.
  • Владимир: и на третьей строке не хватает скобки ) закрывающей if :)

  • Миша: Добрый вечер! Рекомендую получить ID пользователя через функцию get_current_user_id().

  • Дмитрий: Миша, подскажите пожалуйста, я использую такой редирект, но он не срабатывает: add_action( 'template_redirect', funct...

  • Миша: Ну как не определена - это аргумент функции. Или я просто вас не до конца понимаю.

  • Артем: Ага, понял. Вот только почему $args? Она же нигде не определена, по логике должна быть переменная $true_field_params или...