Как переписать функции родительской темы с помощью дочерней темы

Дата публикации:Июль 23, 2015

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

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

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

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

Как работают функции в дочерней и родительской теме

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

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

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

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

Подключаемые функции

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

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

<?php
if ( ! function_exists ( 'my_function' ) ) {
    function my_function() {
        // Contents of your function here.
    }
}
?>

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

Затем вам нужно будет прописать функцию с тем же названием в дочерней теме:

<?php
function my_function() {
    // Contents for your function override here.
}
?>

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

Приоритет функций

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

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

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

<?php
function parent_function() {
    // Contents for your function here.
}
add_action( 'init', 'parent_function' );
?>

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

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

<?php
function child_function() {
    // Contents for your function here.
}
add_action( 'init', 'child_function', 15 );
?>

Функция в вашей родительской теме также может иметь приоритет:

<?php
function parent_function() {
    // Contents for your function here.
}
add_action( 'init', 'parent_function', 20 );
?>

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

<?php
function child_function() {
    // Contents for your function here.
}
add_action( 'init', 'child_function', 25 );
?>

Удаление функций из хуков

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

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

<?php
function parent_function() {
    // Contents for your function here.
}
add_action( 'init', 'parent_function' );
?>

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

<?php
remove_action( 'init', 'parent_function' );
?>

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

<?php
function child_remove_parent_function() {
    remove_action( 'init', 'parent_function' );
}
add_action( 'wp_loaded', 'child_remove_parent_function' );
?>

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

Примечание по поводу приоритетов

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

Если функция в родительской теме имеет вид:

<?php
function parent_function() {
    // Contents for your function here.
}
add_action( 'init', 'parent_function', 15 );
?>

Вам нужно включить то же самое значение приоритета перед удалением функции:

<?php
function child_remove_parent_function() {
    remove_action( 'init', 'parent_function', 15 );
}
add_action( 'wp_loaded', 'child_remove_parent_function' );
?>

Заключение

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

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

Источник: code.tutsplus.com

Поделиться

4 комментария

  1. Дмитрий says:

    Видимо опечятка:

    — remove_action( ‘widgets_init’, ‘parent_function’, 15 );
    + remove_action( ‘init’, ‘parent_function’, 15 );

  2. Отличная статья, очень кстати

  3. webzorg says:

    Отличная статья. Спасибо.

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

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