Дочерние темы — это темы, использующие функциональность родительской темы, но имеющие некоторые отличия: другой дизайн, цвета, дополнительные настройки и т.д. Дочерние темы WordPress используются для того, чтобы ускорить и облегчить процесс разработки веб-сайта. Создание дочерней темы — это один из способов повторного использования кода родительской темы.
Как функционирует дочерняя тема
Файлы дочерней темы загружаются раньше, чем файлы основной темы, благодаря этому любой файл основной темы (за исключением functions.php) можно пересоздать внутри дочерней темы, в этом случае файлы основной темы не будут использоваться. Если WordPress найдет нужный шаблон файла внутри папки дочерней темы, она не станет обращаться к шаблону родительской. Таким образом, можно скопировать любой файл основной темы «к себе» и вносить в него поправки и изменения. Кроме того, можно создавать другие файлы шаблонов, которых не было в родительской теме, расширяя ее функциональность. Это относится ко всем файлам, кроме файла functions.php, с ним происходит нечто иное: так же как и остальные файлами темы, дочерний functions.php загружается ранее, но и родительский файл загружается после него. Это значит, что копировать functions.php «как есть» не получится, но можно создать свой с дополнительными функциями.
Как функционирует файл functions.php
Поскольку загружаются оба файла из двух тем, то дублирование функций с одинаковым названием приведет к критической ошибке php и тема не сможет загрузиться, выдав белый экран. Но для поддержки дочерних тем есть два основных метода, позволяющих дочерней теме переопределить функции родительской темы:
1. Функции, которые заключены в конструкцию
if ( ! function_exists( 'my_function' ) ) : function my_function() { } endif;
Такие функции можно объявлять в файле functions.php дочерней темы и, поскольку тот файл загружается ранее, будет использована функция дочерней темы и благодаря этой проверке не будет критической ошибки. Поэтому, создавая основную тему, можно сразу решить, какие функции нужно сделать перезаписываемыми в дочерних темах.
В дочерней теме объявление будет иметь вид:
function my_function() {
}
2. Функции, которые цепляются к WordPress хукам. Такие функции можно отцеплять в дочерней теме и, таким образом, или отключать эту функцию родительской темы полностью или заменять на свою.
Родительская тема:
function my_function() { } add_action( 'my_hook', 'my_function' );
Убираем этот хук в дочерней теме:
remove_action('my_hook', 'my_function');
И заменяем на свой:
function my_new_function() { } add_action( 'my_hook', 'my_new_function' );
Минимальная тема
Минимальная дочерняя тема состоит из двух файлов:
1. style.css
2. functions.php
Чтобы WordPress увидел новую тему и связал ее с родительской, необходимо указать название родительской темы в комментариях в файле style.css:
/* Theme Name: MyTheme Template: Parent_theme_name Author: YourName Version: 1.0 Text Domain: mytheme */
В файле functions.php необходимо подключить файлы стилей как основной, так и дочерней темы. Ранее стили основной темы подключались через директиву import, а теперь следующим образом:
function mytheme_styles() { wp_enqueue_style( 'mytheme-parent-style', get_template_directory_uri() . '/style.css' ); wp_enqueue_style( 'mytheme-style', get_stylesheet_uri(), array( 'mytheme-parent-style' ) ); } add_action( 'wp_enqueue_scripts', 'mytheme_styles' );
Эти несколько строк описывают основную теорию, далее можно дописывать свои стили и функции внутри дочерней темы, изменяя ее дизайн.
Пример
Для примера я опишу создание дочерней темы для WordPress.org темы Jolene. В ней есть много настроек, которые дочерняя тема должна унаследовать автоматически, кроме того, я добавлю дополнительную четвертую «схему цветов» к уже существующим и переделаю дизайн. В файле functions.php темы Jolene на строке 1205-1232 объявляются параметры темы по умолчанию:
function jolene_get_defaults() { $defaults = array(); $defaults['logotype_url'] = get_template_directory_uri() . '/img/logo.png'; $defaults['is_show_top_menu'] = '1'; $defaults['is_show_secont_top_menu'] = '1'; $defaults['is_show_footer_menu'] = '1'; $defaults['color_scheme'] = 'blue'; $defaults['post_thumbnail'] = 'big'; $defaults['content_width'] = 749; $defaults['content_width_page'] = 960; $defaults['content_width_no_sidebar_page'] = 749; $defaults['content_width_page_no_sidebar_wide'] = 960; $defaults['scroll_button'] = 'right'; $defaults['scroll_animate'] = 'none'; $defaults['favicon'] = ''; $defaults['is_header_on_front_page_only'] = '1'; $defaults['is_text_on_front_page_only'] = '1'; $defaults['is_second_menu_on_front_page_only'] = '1'; $defaults['is_empty_8_on'] = 1; $defaults['is_empty_6_on'] = 0; return apply_filters( 'jolene_option_defaults', $defaults ); }
В конце функции объявлен фильтр, позволяющий дочерним темам изменять настройки по умолчанию. Чтобы изменить параметры в дочерней теме я использую этот фильтр внутри файла functions.php дочерней темы:
function unicorn_option_defaults($defaults){ $defaults['color_scheme'] = 'unicorn'; $defaults['is_second_menu_on_front_page_only'] = '0'; $defaults['is_empty_6_on'] = 1; return $defaults; } add_filter('jolene_option_defaults', 'unicorn_option_defaults');
Здесь я указываю другую схему цветов, включаю второе меню и виджеты в нижним сайдбаре.
Далее нужно добавить новую схему в Настройщик Тем, для этого можно воспользоваться фильтром, объявленным в файле customize.php на строке 1327 основной темы:
function jolene_schemes() { $jolene_schemes = array ('blue' => __( 'Blue', 'jolene' ), 'green' => __( 'Green', 'jolene' ), 'black' => __( 'Black', 'jolene' )); return apply_filters( 'jolene_schemes', $jolene_schemes); }
Добавляю новую схему ‘unicorn’:
function unicorn_schemes($jolene_schemes) { $jolene_schemes['unicorn'] = __( 'Unicorn', 'unicorn' ); return $jolene_schemes; } add_filter('jolene_schemes', 'unicorn_schemes');
В заключении нужно объявить цвета для элементов дочерней темы, для этого есть фильтр в файле customize.php на строке 1240:
$def_colors = apply_filters( 'jolene_def_colors', $def_colors );
И через этот фильтр я добавляю свои цвета:
function unicorn_def_colors($def_colors) { if(get_theme_mod('color_scheme', 'unicorn') == 'unicorn') { //this is color scheme of the child theme $def_colors['site_name_back'] = '#fff'; $def_colors['widget_back'] = '#fff'; $def_colors['link_color'] = '#1e73be'; $def_colors['heading_color'] = '#000'; $def_colors['menu1_color'] = '#fff'; $def_colors['menu1_link'] = '#1e73be'; $def_colors['menu1_hover'] = '#fff'; $def_colors['menu1_hover_back'] = '#1e73be'; $def_colors['menu2_color'] = '#1e73be'; $def_colors['menu2_link'] = '#fff'; $def_colors['menu2_hover'] = '#1e73be'; $def_colors['menu2_hover_back'] = '#eee'; $def_colors['menu3_color'] = '#1e73be'; $def_colors['menu3_link'] = '#fff'; $def_colors['menu3_hover'] = '#1e73be'; $def_colors['menu3_hover_back'] = '#eee'; $def_colors['sidebar1_color'] = '#eee'; $def_colors['sidebar1_link'] = '#1e73be'; $def_colors['sidebar1_hover'] = '#000'; $def_colors['sidebar1_text'] = '#333'; $def_colors['sidebar2_color'] = '#fff'; $def_colors['sidebar2_link'] = '#1e73be'; $def_colors['sidebar2_hover'] = '#000'; $def_colors['sidebar2_text'] = '#828282'; //columns $def_colors['sidebar3_color'] = '#eee'; $def_colors['sidebar3_link'] = '#1e73be'; $def_colors['sidebar3_hover'] = '#000066'; $def_colors['sidebar3_text'] = '#999'; $def_colors['column_header_color'] = '#eee'; $def_colors['column_header_text'] = '#000'; $def_colors['border_color'] = '#fff'; $def_colors['border_shadow_color'] = '#bfbfbf'; } return $def_colors; } add_filter('jolene_def_colors', 'unicorn_def_colors');
Кроме этого, в файле style.css немного изменены отступы и стиль, используется другой шрифт и добавлен свой домен для перевода на другие языки и немного изменена функция загрузки основной темы.
functions.php дочерней темы полностью
<?php /** * Functions and definitions * * @package WordPress * @subpackage Unicorn * @since Unicorn 1.0 */ /** * Unicorn setup. * * @since Unicorn 1.0 */ function unicorn_setup() { remove_action('jolene_empty_sidebar_6', 'jolene_empty_sidebar_6'); load_child_theme_textdomain( 'unicorn', get_stylesheet_directory() . '/languages' ); } add_action( 'after_setup_theme', 'unicorn_setup' ); /** * New Jolene setup. * * Set up theme defaults and registers support for various WordPress features. * * @since unicorn 1.0 */ function jolene_setup() { $defaults = jolene_get_defaults(); if ( get_theme_mod( 'is_show_top_menu', $defaults ['is_show_top_menu']) == '1' ) register_nav_menu( 'top1', __( 'First Top Menu', 'jolene' )); if ( get_theme_mod( 'is_show_secont_top_menu', $defaults ['is_show_secont_top_menu']) == '1' ) register_nav_menu( 'top2', __( 'Second Top Menu', 'jolene' )); if ( get_theme_mod( 'is_show_footer_menu', $defaults ['is_show_footer_menu']) == '1' ) register_nav_menu( 'footer', __( 'Footer Menu', 'jolene' )); load_theme_textdomain( 'jolene', get_template_directory() . '/languages' ); add_theme_support( 'automatic-feed-links' ); add_theme_support( 'custom-background', array( 'default-color' => 'cccccc', ) ); add_theme_support( 'post-thumbnails' ); set_post_thumbnail_size( 300, 9999 ); add_image_size( 'jolene-full-width', jolene_big_thumbnail_size());//big thumbnail add_image_size( 'jolene-full-screen', 1309);//large thumbnail $args = array( 'default-image' => '', 'default-text-color' => '000000', 'width' => 1309, 'height' => 200, 'flex-height' => true, 'flex-width' => false, 'wp-head-callback' => 'jolene_header_style', 'admin-head-callback' => 'jolene_admin_header_style', 'admin-preview-callback' => 'jolene_admin_header_image', ); add_theme_support( 'custom-header', $args ); /* * Enable support for Post Formats. */ add_theme_support( 'post-formats', array( 'aside', 'image', 'video', 'audio', 'quote', 'link', 'gallery', ) ); add_theme_support( 'html5', array( 'search-form', 'comment-form', 'comment-list', 'caption' ) ); add_theme_support( 'title-tag' ); /* * Enable support for WooCommerce plugin. */ add_theme_support( 'woocommerce' ); } add_action( 'after_setup_theme', 'jolene_setup' ); /** * Return the Google font stylesheet URL if available. * * @since unicorn 1.0 */ function unicorn_get_font_url() { $font_url = ''; /* translators: If there are characters in your language that are not supported * by Open Sans fonts, translate this to 'off'. Do not translate into your own language. */ if ( 'off' !== _x( 'on', 'Open Sans font: on or off', 'unicorn' ) ) { $subsets = 'latin,latin-ext'; $family = 'Open+Sans:400italic,400,300'; /* translators: To add an additional Open Sans character subset specific to your language, * translate this to 'greek', 'cyrillic' or 'vietnamese'. Do not translate into your own language. */ $subset = _x( 'no-subset', 'Font: add new subset (greek, cyrillic, vietnamese)', 'unicorn' ); if ( 'cyrillic' == $subset ) { $subsets .= ',cyrillic,cyrillic-ext'; } if ( 'greek' == $subset ) $subsets .= ',greek,greek-ext'; elseif ( 'vietnamese' == $subset ) $subsets .= ',vietnamese'; $query_args = array( 'family' => $family, 'subset' => $subsets, ); $font_url = add_query_arg( $query_args, "//fonts.googleapis.com/css" ); } return $font_url; } /** * Enqueue parent and child scripts * * @package WordPress * @subpackage Unicorn * @since Unicorn 1.0 */ function unicorn_enqueue_styles() { wp_enqueue_style( 'unicorn-parent-style', get_template_directory_uri() . '/style.css' ); wp_enqueue_style( 'unicorn-style', get_stylesheet_uri(), array( 'unicorn-parent-style' ) ); $font_url = unicorn_get_font_url(); if ( ! empty( $font_url ) ) wp_enqueue_style( 'unicorn-fonts', esc_url_raw( $font_url ), array(), null ); } add_action( 'wp_enqueue_scripts', 'unicorn_enqueue_styles' ); /** * Unregister fonts * * @since unicorn 1.0 */ function unicorn_dequeue_styles() { wp_dequeue_style('jolene-fonts'); } add_action( 'wp_print_styles', 'unicorn_dequeue_styles' ); /** * Print Demo Widget into the empty sidebar-6. * * @since Unicorn 1.0 */ function unicorn_empty_sidebar_6() { the_widget( 'WP_Widget_Calendar', 'title='.__('Calendar', 'unicorn'), 'before_widget=<div class="widget-wrap"><aside class="widget">&after_widget=</aside></div>&before_title=<h3 class="widget-title">&after_title=</h3>'); the_widget( 'WP_Widget_Recent_Posts', 'title='.__('Recent Posts', 'unicorn').'&sortby=post_modified', 'before_widget=<div class="widget-wrap"><aside class="widget">&after_widget=</aside></div>&before_title=<h3 class="widget-title">&after_title=</h3>'); the_widget( 'WP_Widget_Search', 'title='.__('Search', 'unicorn'), 'before_widget=<div class="widget-wrap"><aside class="widget widget_search">&after_widget=</aside></div>&before_title=<h3 class="widget-title">&after_title=</h3>'); } add_action('jolene_empty_sidebar_6', 'unicorn_empty_sidebar_6'); /** * Unicorn setup. * * Filter for theme defaults. * * @since Unicorn 1.0 */ function unicorn_option_defaults($defaults){ $defaults['color_scheme'] = 'unicorn'; $defaults['is_second_menu_on_front_page_only'] = '0'; $defaults['is_empty_6_on'] = 1; return $defaults; } add_filter('jolene_option_defaults', 'unicorn_option_defaults'); /** * Unicorn Color scheme. * * Default Colors for the child theme Unicorn. * * @since Unicorn 1.0 */ function unicorn_def_colors($def_colors) { if(get_theme_mod('color_scheme', 'unicorn') == 'unicorn') { //this is color scheme of the child theme $def_colors['site_name_back'] = '#fff'; $def_colors['widget_back'] = '#fff'; $def_colors['link_color'] = '#1e73be'; $def_colors['heading_color'] = '#000'; $def_colors['menu1_color'] = '#fff'; $def_colors['menu1_link'] = '#1e73be'; $def_colors['menu1_hover'] = '#fff'; $def_colors['menu1_hover_back'] = '#1e73be'; $def_colors['menu2_color'] = '#1e73be'; $def_colors['menu2_link'] = '#fff'; $def_colors['menu2_hover'] = '#1e73be'; $def_colors['menu2_hover_back'] = '#eee'; $def_colors['menu3_color'] = '#1e73be'; $def_colors['menu3_link'] = '#fff'; $def_colors['menu3_hover'] = '#1e73be'; $def_colors['menu3_hover_back'] = '#eee'; $def_colors['sidebar1_color'] = '#eee'; $def_colors['sidebar1_link'] = '#1e73be'; $def_colors['sidebar1_hover'] = '#000'; $def_colors['sidebar1_text'] = '#333'; $def_colors['sidebar2_color'] = '#fff'; $def_colors['sidebar2_link'] = '#1e73be'; $def_colors['sidebar2_hover'] = '#000'; $def_colors['sidebar2_text'] = '#828282'; //columns $def_colors['sidebar3_color'] = '#eee'; $def_colors['sidebar3_link'] = '#1e73be'; $def_colors['sidebar3_hover'] = '#000066'; $def_colors['sidebar3_text'] = '#999'; $def_colors['column_header_color'] = '#eee'; $def_colors['column_header_text'] = '#000'; $def_colors['border_color'] = '#fff'; $def_colors['border_shadow_color'] = '#bfbfbf'; } return $def_colors; } add_filter('jolene_def_colors', 'unicorn_def_colors'); /** * Add Unicorn Color scheme to the list of color schemes. * * @since Unicorn 1.0 */ function unicorn_schemes($jolene_schemes) { $jolene_schemes['unicorn'] = __( 'Unicorn', 'unicorn' ); return $jolene_schemes; } add_filter('jolene_schemes', 'unicorn_schemes'); /** * Set Unicorn def background to ''. * * @since Unicorn 1.0 */ function unicorn_column_background($jolene_schemes) { return ''; } add_filter('jolene_column_background', 'unicorn_column_background'); /** * Enqueue Javascript postMessage handlers for the Customizer. * * Binds JS handlers to make the Customizer preview reload changes asynchronously. * * @since Unicorn 1.0 */ function unicorn_customize_preview_js() { wp_enqueue_script( 'unicorn-customizer', get_stylesheet_directory_uri() . '/js/theme-customizer.js', array( 'customize-preview' ), time(), true ); } add_action( 'customize_preview_init', 'unicorn_customize_preview_js', 99 );
style.css дочерней темы полнотью
/* Theme Name: Unicorn Template: jolene Version: 1.0 License: GNU General Public License v2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html Text Domain: unicorn This theme, like WordPress, is licensed under the GPL. Use it to make something cool, have fun, and share what you've learned with others. */ h1, h2, h3, h4, h5, h6 { font-weight: 300; } input, textarea { border: 1px solid #ccc; } .site { font-family: 'Open Sans', sans-serif; } #masthead #menu-1 { border: none; } #top-1-navigation { border-bottom: 1px solid #ccc; box-shadow: 0 4px 2px rgba(0, 0, 0, 0.2); } #masthead #menu-1 a, #menu-2 a, #menu-3 a { text-shadow: none; } #top-navigation { margin: 0 0 20px 0; } .site-title { font-size: 36px; font-family: 'Open Sans', sans-serif; } .site-info-text-top { border-bottom: 1px solid #eee; } .site-info-text-top a{ display: block; text-align: center; } .site-info-text-top .site-title a { color: #ccc; font-family: 'Open Sans', sans-serif; font-weight: 300; padding: 0 20px; text-decoration: none; font-size: 26px; text-transform: uppercase; } .site-description { color: #999; display: none; } .img-container, .site-info-text { margin-top: 20px; } .site-title { margin-top: 0; } .sidebar-header-right { margin: 0 auto; } #menu-1 .menu-toggle { float: right; margin: 0 20px 0 0; } #menu-1 div { clear: both; padding-bottom: 20px; } .header-wrapper { background: #fff; } .widget.jolene_socialicons { padding-bottom: 0 !important; } .horizontal.big li { height: 60px; width: 60px; } .column .widget .after-widget-title { background: none; } .column .widget .widget-title { border: none; } .sidebar-left { max-width: 280px; } .sidebar-left { margin-left: 10px; margin-top: 0; } .sidebar-right{ margin-right: 10px; margin-top: 0; max-width: 280px; } .column .widget { box-shadow: 0 4px 4px rgba(0, 0, 0, 0.3); margin-bottom: 20px; margin-top: 0 !important; } .column { padding-top: 0; } .site-content { margin-top: 20px !important; } .site-content .entry-title { border-bottom: 1px solid #eee; font-weight: 300; text-align: center; } .site-content .entry-title a { text-decoration: none; } .image-and-cats-big .category-list, .image-and-cats .category-list { background: transparent !important; } .horizontal-navigation a, .image-and-cats-big .category-list a, .image-and-cats .category-list a, .site-cat a { font-weight: 300; } .image-and-cats-big { margin-top: 0 !important; padding-top: 0 !important; } .image-and-cats-big .category-list { padding-left: 20px; padding-right: 20px; text-align: right; } .sticky { border: none; } .archive-title { font-size: 14px; text-transform: uppercase; } #sidebar-1 .widget_search .search-form input[type="search"] { margin: 20px; } #sidebar-1 .search-submit { display: none; } #sidebar-1 .widget_search .search-form input[type="search"] { display: block; margin: 0 auto; width: 40%; } .sidebar-footer ul { list-style: none; } .image-and-cats-large { background: url(texture.jpg) repeat center center fixed; } /* Genericons Icons */ .sidebar-footer li:before, .column li:before { color: #fff; content: '\f428'; display: inline-block; -webkit-font-smoothing: antialiased; font: normal 32px/1 'Genericons'; padding-right: 5px; text-shadow: 0 2px 2px rgba(0, 0, 0, 0.2); vertical-align: middle; } .sidebar-footer .widget_search .search-form input[type="search"] { width: 100%; } .sidebar-footer .widget-wrap { margin: 0 auto; width: 90%; } .sidebar-before-footer .widget-title, .sidebar-top-full .widget-title, .sidebar-top .widget-title, .sidebar-content .widget-title { border-bottom: 1px solid #eee; font-weight: 300; text-align: center; } .category-list a, .sidebar-top-full a, .sidebar-before-footer a, .sidebar-top a, .sidebar-content a { font-weight: 300; } .footer-list a { border-bottom: 1px solid #eee; text-align: center; text-decoration: none; } .widget.jolene_extended .widget-title { margin-bottom: 10px; } .category-list .site-title { position: relative; } @media screen and (min-width: 680px) { .horisontal-navigation .current-menu-item > a, .horisontal-navigation .current-menu-ancestor > a, .horisontal-navigation .current_page_item > a, .horisontal-navigation .current_page_ancestor > a { background-image: linear-gradient( rgba(77, 151, 153, 0.1), rgba(77, 151, 153, 0.1)); } #menu-1 div { clear: none; padding-bottom: 0; } .site-info-text-top a{ display: inline-block; } } @media screen and (min-width: 960px) { #sidebar-1 .widget_search .search-form input[type="search"] { width: 40%; } .site-description { display: block; } } @media screen and (min-width: 940px) { .sidebar-footer { padding: 0 10%; } .sidebar-footer .widget-wrap { display: inline-block; vertical-align: top; width: 33.3333%; } .sidebar-footer .widget-title { border-bottom: 10px solid #eee; text-align: center; } #sidebar-1 .widget_search .search-form input[type="search"] { width: 40%; } }
В итоге получаем дочернюю тему со всеми функциями и настройками оригинала.
Скрин:
Устанавливается дочерняя тема точно так же как и основная. Загрузка основной темы осуществляется самим WordPress с сайта WordPress.org, все необходимые файлы подгружаются незаметно для пользователя. Кроме того, если в основной теме появятся изменения (новые функции или исправления), дочерняя тема унаследует их, не потеряв свои уникальные стили и настройки. Очень важно использовать правильные хуки в основной теме, чтобы дочерняя тема имела возможность их изменять.
Источник: http://habrahabr.ru/post/248209