Статьи

Как изменить поведение родительской темы в детской теме

Каковы детские темы ? Дочерние темы — это полезная функция WordPress, которая позволяет разработчикам создавать новый шаблон, не начиная с нуля, а используя все функции, уже имеющиеся в существующей теме.

Иногда, однако, родительская тема, которую мы выбрали для нашего сайта, может иметь некоторые функции, которые нам не нужны (или нам нужно настроить в соответствии с нашими потребностями), например, настраиваемые типы записей с другим слагом, шорткоды, библиотеки JavaScript, размеры изображений, которые мы не используем и так далее …


Хотя может быть легко достичь того, что мы хотим, путем непосредственного редактирования темы, также верно, что каждый раз, когда тема будет обновляться, нам придется снова выполнять все настройки. Это может разочаровать, поэтому есть еще один вариант: мы можем создать дочернюю тему и использовать файл > functions.php > для изменения функций родительской темы . Таким образом, мы можем обновлять родительскую тему каждый раз, когда выпускается новая версия, не теряя наших настроек.

Прежде чем перейти к более конкретным деталям, сделаем краткое замечание о внешнем виде темы: мы можем изменить цвета, фоны, типографику и макет с помощью файла style.css дочерней темы, импортировав родительский файл style.css и переопределив нужные нам стили. изменить.

Для большего контроля над макетом мы также можем следить за тем, как Аббас Сутервала предлагает в своем посте, и клонировать родительские файлы пользовательских шаблонов в нашей дочерней теме:

Затем дочерняя тема может при желании переопределить другие файлы шаблона, такие как author.php , category.php и т. Д. Платформа WordPress сначала ищет файл шаблона в каталоге дочерней темы, а затем, если не найден, забирает его из родительского каталога.


Через файл functions.php дочерней темы мы можем иметь дело с:

  • Особенности темы
  • Пользовательские типы сообщений и таксономии
  • Меню и боковые панели
  • Виджеты
  • Шорткоды
  • Дополнительные размеры изображения
  • метабоксы
  • JavaScript и CSS
  • Действия и фильтры родительской темы

Итак, допустим, у нас есть такая структура сайта:

  • htdocs или www
    • WP-содержание
      • темы
        • foo-theme (каталог родительской темы — он не будет изменен)
          • functions.php
          • header.php
          • style.css
          • другие файлы шаблонов …
        • foo-theme-child (каталог нашей дочерней темы)
          • functions.php (файл, который мы будем использовать для настройки родительской темы)
          • header.php (переопределяет header.php для родительской темы)
          • style.css (это обязательный файл в дочерней теме и должен называться style.css )

Давайте начнем: создайте пустой файл functions.php в каталоге / wp-content / themes / foo-theme-child / .

По большей части мы будем использовать универсальную wp_tuts_remove_features() , подключенную к действию WordPress after_setup_theme . Мы также устанавливаем 10 в качестве третьего параметра (приоритета), поэтому мы уверены, что функция запускается перед родительским.

1
2
3
4
5
add_action( ‘after_setup_theme’, ‘remove_parent_theme_features’, 10 );
 
function remove_parent_theme_features() {
    // our code here
}

Некоторые родительские темы добавляют функции в WordPress через функцию add_theme_support .

Доступные функции:

  • post-formats
  • post-thumbnails
  • custom-background
  • custom-header
  • automatic-feed-links

Таким образом, чтобы удалить их, мы можем изменить remove_parent_theme_features() в файле functions.php .

1
2
3
4
5
6
7
function remove_parent_theme_features() {
    remove_theme_support( ‘post-formats’ );
    remove_theme_support( ‘post-thumbnails’ );
    remove_theme_support( ‘custom-background’ );
    remove_theme_support( ‘custom-header’ );
    remove_theme_support( ‘automatic-feed-links’ );
}

Удалить пользовательские типы parent_movie_add_post_type() и пользовательские таксономии легко: если родительский файл functions.php добавляет пользовательский тип записи Movie через функцию parent_movie_add_post_type() :

01
02
03
04
05
06
07
08
09
10
11
12
13
// PARENT functions.php
 
add_action( ‘after_setup_theme’, ‘parent_movie_add_post_type’ );
 
function parent_movie_add_post_type() {
 
    $parent_args = array(
        // other arguments…
        ‘rewrite’ => array( ‘slug’ => ‘movie’ ),
        ‘supports’ => array( ‘title’, ‘editor’, ‘author’, ‘excerpt’ )
    );
    register_post_type( ‘movie’, $parent_args );
}

… мы можем настроить его благодаря нашему дочернему файлу functions.php :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// CHILD functions.php
 
function remove_parent_theme_features() {
    // remove Movie Custom Post Type
    remove_action( ‘init’, ‘parent_movie_add_post_type’ );
    /*
    alternatively, we can add our custom post type to
    overwrite only some aspects of the parent function
    */
    add_action( ‘init’, ‘child_movie_post_type’ );
}
 
function child_movie_post_type() {
    $child_args = array(
        // other arguments…
        // change Custom Post slug
        ‘rewrite’ => array( ‘slug’ => ‘child-movie’ ),
        // remove excerpts and add post thumbs
        ‘supports’ => array( ‘title’, ‘editor’, ‘author’, ‘thumbnail’ )
    );
 
    register_post_type( ‘movie’, $child_args );
}

Мы также можем удалить только определенные функции без отмены регистрации типа записи, например, если мы хотим заменить поле выдержки изображением с публикацией, мы можем изменить функцию следующим образом:

01
02
03
04
05
06
07
08
09
10
function remove_parent_theme_features() {
    add_action( ‘init’, ‘wp_tuts_remove_post_feature’ );
}
 
function wp_tuts_remove_post_feature() {
    // remove excerpt
    remove_post_type_support( ‘movie’, ‘excerpt’ );
    // add post thumbs
    add_post_type_support( ‘movie’, ‘thumbnail’ );
}

Вы можете найти полный список съемных функций в разделе remove_post_type_support в Кодексе WordPress.

Подобно пользовательским типам parent_taxonomy() , вы можете удалить пользовательскую таксономию, добавленную в родительскую тему, с помощью функции parent_taxonomy() следующим образом:

1
2
3
function wp_tuts_after_setup_theme() {
    remove_action( ‘init’, ‘parent_taxonomy’ );
}

Мы можем удалить меню родительской темы через функцию unregister_nav_menu() . Эта функция принимает один параметр — слаг идентификатора расположения меню, используемый в функции register_nav_menu() .

Если родительская тема регистрирует меню заголовка :

1
2
3
4
5
6
7
// PARENT functions.php
 
add_action( ‘after_setup_theme’, ‘register_my_menu’ );
 
function register_my_menu() {
    register_nav_menu( ‘header-menu’, __( ‘Header Menu’ ) );
}

Мы можем удалить это следующим образом:

1
2
3
4
5
// CHILD functions.php
 
function remove_parent_theme_features() {
    unregister_nav_menu( ‘header-menu’ );
}

Чтобы идентифицировать зарегистрированные меню, мы можем искать код родительской темы для вызовов register_nav_menu() . Первый аргумент функции представляет идентификатор меню, который мы можем использовать для отмены регистрации (в данном случае header-menu ).


WordPress поставляется с некоторыми виджетами по умолчанию, которые мы можем отключить. Кроме того, наша родительская тема может добавлять свои собственные виджеты, поэтому мы можем искать в файлах темы, ища, где они объявлены, и записывать их имя. Обычно они объявляются в классе PHP, который расширяет класс WP_Widget :

1
2
3
4
// PARENT theme
class ParentWidgetName extends WP_Widget {
    // widget code
}

Итак, чтобы ParentWidgetName регистрацию виджета, мы используем имя класса ParentWidgetName :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
add_action( ‘widgets_init’, ‘wp_tuts_parent_unregister_widgets’, 10 );
 
function wp_tuts_parent_unregister_widgets() {
 
    // remove (some) WordPress default Widgets
    unregister_widget( ‘WP_Widget_Pages’ );
    unregister_widget( ‘WP_Widget_Calendar’ );
 
    // remove Parent registered Widget
    unregister_widget( ‘ParentWidgetName’ );
 
    // register a custom Widget (if needed)
    register_widget( ‘MyCustomWidget’ );
}
 
// don’t forget to add the Widget Class
class MyCustomWidget extends WP_Widget {
    // Custom Widget code
}

Для боковых панелей действие аналогично:

1
2
3
4
5
6
add_action( ‘widgets_init’, ‘wp_tuts_parent_unregister_sidebars’, 10 );
 
function wp_tuts_parent_unregister_sidebars() {
    // remove a sidebar registered by the Parent Theme
    unregister_sidebar( ‘first-footer-widget-area’ );
}

Чтобы идентифицировать зарегистрированные боковые панели, мы можем искать код родительской темы для вызовов register_sidebar() .

Все, что нам нужно, это принять к сведению идентификатор боковой панели:

1
2
3
4
5
6
7
8
// PARENT functions.php
 
$args = array(
    ‘id’ => ‘first-footer-widget-area’,
    // other args…
);
 
register_sidebar( $args );

Переопределить или удалить шорткоды легко, нам нужно только изменить нашу функцию следующим образом:

01
02
03
04
05
06
07
08
09
10
function remove_parent_theme_features() {
    // remove the parent [gmap] shortcode
    remove_shortcode( ‘gmap’ );
    // add our [gmap] shortcode
    add_shortcode( ‘gmap’, ‘child_shortcode_gmap’ );
}
 
function child_shortcode_gmap( $atts ) {
    // create our shortcode that overwrites the parent one
}

Чтобы идентифицировать зарегистрированные шорткоды, мы можем искать код родительской темы для add_shortcode() . Первый параметр — это тот, который мы ищем ;-).


Если родительская тема добавляет новые размеры изображений, которые мы не используем в нашей дочерней теме, мы можем искать код родительской темы для add_image_size() . В этом случае это: custom_size_parent_1 и custom_size_parent_2 . Мы сбрасываем их таким образом:

1
2
3
4
5
6
7
add_filter( ‘intermediate_image_sizes_advanced’, ‘remove_parent_image_sizes’ );
 
function remove_parent_image_sizes( $sizes ) {
    unset( $sizes[‘custom_size_parent_1’] );
    unset( $sizes[‘custom_size_parent_2’] );
    return $sizes;
}

Это полезно, потому что каждый раз, когда пользователь загружает изображение, WordPress не будет создавать дополнительные размеры изображений, которые мы не используем.

Для создания пользовательских размеров изображения мы можем добавить это в наш дочерний файл functions.php :

1
2
3
4
5
6
if ( function_exists( ‘add_image_size’ ) ) {
    // 400 pixels wide and unlimited height
    add_image_size( ‘custom_size_child_1’, 400, 9999 );
    // 320 pixels wide and 240 px tall, cropped
    add_image_size( ‘custom_size_child_2’, 320, 240, true );
}

С помощью функции remove_meta_box() мы можем удалить как метабоксы WordPress по умолчанию, так и родительские темы.

Список метабоксов WordPress по умолчанию доступен в разделе remove_meta_box() Кодекса WordPress. Функция имеет три аргумента: идентификатор метабокса, страница, с которой он будет удален, контекст редактирования ( normal , advanced , side ).

Если родительская тема добавляет метабоксы на экране редактирования сообщения, мы можем отключить их следующим образом:

1
2
3
4
5
6
7
8
add_action( ‘admin_menu’ , ‘wp_tuts_remove_metaboxes’, 99 );
 
function wp_tuts_remove_metaboxes() {
    // remove default WP Trackback Metabox from Posts editing page
    remove_meta_box( ‘trackbacksdiv’, ‘post’, ‘normal’ );
    // remove a Parent Theme Metabox ‘parent_post_foo_metabox’
    remove_meta_box( ‘parent_post_foo_metabox’, ‘post’, ‘normal’ );
}

Мы можем определить родительские метабоксы путем поиска кода родительской темы для add_meta_box или add_meta_boxes() .

Идентификатор метабокса, который нужно удалить, является первым аргументом функции add_meta_box() .


Если родительская тема добавляет стили JavaScript и CSS, которые нам не нужны:

01
02
03
04
05
06
07
08
09
10
11
12
// PARENT functions.php
 
add_action( ‘wp_print_scripts’, ‘parent_scripts’ );
add_action( ‘wp_print_styles’, ‘parent_styles’ );
 
function parent_scripts() {
    wp_enqueue_script( ‘fancybox-parent-js’, get_stylesheet_directory_uri() . ‘/fancybox/jquery.fancybox.pack.js’ );
}
 
function parent_styles() {
    wp_enqueue_style( ‘fancybox-parent-css’, get_stylesheet_directory_uri() . ‘/fancybox/jquery.fancybox.css’ );
}

Мы можем удалить их следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
// CHILD functions.php
 
add_action( ‘wp_print_scripts’, ‘child_overwrite_scripts’, 100 );
add_action( ‘wp_print_styles’, ‘child_overwrite_styles’, 100 );
 
function child_overwrite_scripts() {
    wp_deregister_script( ‘fancybox-parent-js’ );
}
 
function child_overwrite_styles() {
    wp_deregister_style( ‘fancybox-parent-css’ );
}

Чтобы идентифицировать зарегистрированные JavaScripts и CSS-стили, мы можем wp_enqueue_script() поиск кода родительской темы для wp_enqueue_script() и wp_enqueue_style() .

Первый аргумент функции — это то, что мы можем использовать в wp_deregister_script() или wp_deregister_style() .


Некоторые темы, такие как Thematic, предоставляют несколько хуков для изменения поведения темы без изменения файлов темы. В этом случае Thematic предоставляет действие thematic_header которое загружает другие действия:

  • thematic_brandingopen()
  • thematic_blogtitle()
  • thematic_blogdescription()
  • thematic_brandingclose()
  • thematic_access()

Мы не будем подробно рассматривать, что делают эти функции, возможно, некоторые из них выводят некоторую информацию в заголовке блога: name, description и т. Д. … В этом случае мы можем деактивировать функцию thematic_blogdescription() следующим образом:

1
2
3
4
5
6
7
// Unhook default Thematic functions
function unhook_thematic_functions() {
    // we put the position number of the original function (5)
    // for priority reasons
    remove_action( ‘thematic_header’, ‘thematic_blogdescription’, 5 );
}
add_action( ‘init’, ‘unhook_thematic_functions’ );

В этих случаях может быть трудно понять структуру родительской темы и как она работает. Мой совет — выбрать родительскую тему, которая поставляется с подробной документацией, хорошим форумом поддержки и делает доступными хуки во всем коде.

Это, безусловно, заставляет нас терять время на разработку и упрощает настройку дочерней темы.