Статьи

Руководство по переопределению функций родительской темы в теме вашего ребенка

Если у вас есть опыт работы с родительскими и дочерними темами в WordPress, вы будете знать, что файлы шаблонов в вашей дочерней теме имеют приоритет над файлами в вашей родительской теме. Например, если ваша родительская тема имеет файл page.php и вы создаете новый файл в своей дочерней теме, WordPress будет использовать файл в дочерней теме при отображении страниц.

Вы можете подумать, что функции будут работать таким же образом: создайте новую функцию в файле functions.php вашей дочерней темы с тем же именем, что и в родительской теме, и она будет иметь приоритет. К сожалению, не все так просто.

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

  • подключаемые функции
  • приоритет функции
  • удаление функций из крючка, к которому они прикреплены

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

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

Функции в вашей дочерней теме будут загружены перед функциями в родительской теме. Это означает, что если у вашей родительской и дочерней тем есть функции с именем my_function() которые выполняют аналогичную работу, функция в родительской теме будет загружаться последней, то есть переопределит функцию в дочерней теме.

Однако вы можете изменить порядок запуска функций, а также запретить запуск функций в целом, как мы вскоре увидим.

Сменные функции — это то, что вы кодируете в своей родительской теме, поэтому они не будут вам полезны, если вы работаете с существующей родительской темой, у которой их нет.

Но если вы пишете свою собственную родительскую тему, возможно, в качестве отправной точки для будущих проектов, или если вы создаете свою собственную платформу тем, рекомендуется сделать свои функции подключаемыми, чтобы их можно было легко переопределить в дочерних темах. Также неплохо бы просмотреть функции, которые написаны в родительской теме, которую вы используете, поскольку многие из них, включая тему по умолчанию WordPress, будут иметь подключаемые функции.

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

1
2
3
4
5
6
7
<?php
if ( ! function_exists ( ‘my_function’ ) ) {
    function my_function() {
        // Contents of your function here.
    }
}
?>

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

Затем, когда вы пишете функцию в своей дочерней теме, которую хотите переопределить в родительской теме, вы просто даете ей то же имя, что и в родительской теме:

1
2
3
4
5
<?php
function my_function() {
    // Contents for your function override here.
}
?>

WordPress сначала запустит функцию в дочерней теме, а когда она перейдет к функции в родительской теме, он проверит, существует ли она, и, поскольку она существует, не запустит ее.

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

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

Давайте представим, что функция в родительской теме не подключаема и выглядит так:

1
2
3
4
5
6
<?php
function parent_function() {
    // Contents for your function here.
}
add_action( ‘init’, ‘parent_function’ );
?>

Эта функция прикреплена к init и ей не был дан приоритет. По умолчанию WordPress назначает приоритет 10 функциям, для которых не был добавлен приоритет, поэтому для запуска вашей функции после нее используется число больше 10 . Я склонен использовать 15 поэтому у меня есть немного места для дыхания на случай, если я захочу добавить еще одну функцию между ними позже.

Это означает, что функция в вашей дочерней теме будет выглядеть так:

1
2
3
4
5
6
<?php
function child_function() {
    // Contents for your function here.
}
add_action( ‘init’, ‘child_function’, 15 );
?>

Кроме того, функции в вашей родительской теме может быть назначен приоритет:

1
2
3
4
5
6
<?php
function parent_function() {
    // Contents for your function here.
}
add_action( ‘init’, ‘parent_function’, 20 );
?>

Так что вам просто нужно убедиться, что приоритет, который вы даете функции в вашей дочерней теме, выше:

1
2
3
4
5
6
<?php
function child_function() {
    // Contents for your function here.
}
add_action( ‘init’, ‘child_function’, 25 );
?>

Иногда запуска другой функции после первой недостаточно, чтобы переопределить ее — необходимо убедиться, что функция в родительской теме вообще не запускается. В этом случае вы можете удалить родительскую функцию темы из ловушки, к которой она присоединена, используя функции remove_action() или remove_filter() . То, что вы будете использовать, будет зависеть от того, присоединена ли функция к ловушке действия или ловушке фильтра в родительской теме.

Итак, давайте вернемся к нашей предыдущей функции в родительской теме:

1
2
3
4
5
6
<?php
function parent_function() {
    // Contents for your function here.
}
add_action( ‘init’, ‘parent_function’ );
?>

Чтобы удалить эту функцию из ловушки действий и, следовательно, предотвратить ее запуск, вы создаете функцию в своей дочерней теме, чтобы удалить ее с помощью remove_action() :

1
2
3
<?php
remove_action( ‘init’, ‘parent_function’ );
?>

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

1
2
3
4
5
6
<?php
function child_remove_parent_function() {
    remove_action( ‘init’, ‘parent_function’ );
}
add_action( ‘wp_loaded’, ‘child_remove_parent_function’ );
?>

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

Обратите внимание, что если вы пытаетесь удалить функцию с помощью remove_action() или remove_filter() и ей назначен приоритет, вы должны включить приоритет при удалении, иначе он не будет работать.

Так что, если функция в родительской теме выглядит так:

1
2
3
4
5
6
<?php
function parent_function() {
    // Contents for your function here.
}
add_action( ‘init’, ‘parent_function’, 15 );
?>

… при удалении вам нужно будет включить одно и то же значение приоритета:

1
2
3
4
5
6
<?php
function child_remove_parent_function() {
    remove_action( ‘widgets_init’, ‘parent_function’, 15 );
}
add_action( ‘wp_loaded’, ‘child_remove_parent_function’ );
?>

Переопределение функций в родительской теме сложнее, чем переопределение файлов шаблонов или стилей, но это можно сделать. Здесь я показал вам три способа сделать это:

  • Если вы пишете собственную родительскую тему или используете ту, которая имеет их, используйте подключаемые функции, чтобы заменить ее в функции дочерней темы с тем же именем, что и в родительской теме.
  • Присвойте более высокие приоритеты функциям в ваших дочерних темах, чтобы они выполнялись после функций в вашей родительской теме.
  • Используйте remove_action() или remove_filter() для remove_filter() удаления функций из родительской темы.

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