Хуки действий и фильтров являются фундаментальной частью различных API WordPress. Без них вы ограничены тем, что вы можете делать в своих темах и (особенно) в своих плагинах.
Но иногда их легко спутать, особенно в тех случаях, когда WordPress имеет как ловушку действия, так и ловушку фильтра с одним и тем же именем.
В этой статье я опишу хуки действий и фильтров и опишу разницу между ними, а также продемонстрирую, как их использовать в ваших темах и плагинах. Я также приведу несколько примеров того, когда вы можете использовать каждый из них.
Когда вы добавляете хуки действий и фильтров к своему коду (или вы привязываете к ним функции), это помогает понять, как WordPress вызывает действия и фильтры и что происходит в каком порядке. Я не буду подробно останавливаться на этом здесь, так как у нас есть другой учебник, который выполняет эту работу.
Определения и различия
Давайте начнем с некоторых определений. Я также определю действия, фильтры и функции, чтобы вы могли увидеть разницу между ними.
функции
Функции — это первое, с чем большинство людей работают, изучая разработку WordPress; если вы добавили код в файл functions.php
вашей темы, то вы написали функцию.
Функции определяют, как что-то произойдет. Вы кодируете функцию для запроса данных, для вывода содержимого или для выполнения многих других задач. Вы можете вызывать (выполнять) функции непосредственно в файлах шаблонов вашей темы, или вы можете привязать их к действиям или фильтрам. Функции могут также включать теги шаблона, такие как условные теги, чтобы указать, когда функция должна применяться.
Я покажу вам различные способы выполнения функций позже в этой статье.
Action Hooks
Хуки действий (или действия) срабатывают, когда что-то происходит, например, загрузка страницы, вход пользователя в систему или пользовательское действие, которое вы определяете в своей теме или плагине.
Вы можете добавить свои собственные do_action()
действий с помощью функции do_action()
, которую я продемонстрирую в ближайшее время. Любые функции, которые вы подключаете к этому действию, будут выполняться в этой точке кода.
Крючки фильтра
Фильтры-хуки или фильтры контролируют, как что-то происходит, или изменяют то, что уже выводится. Вы можете использовать фильтр для вывода метаданных в определенном формате, для переопределения вывода текста вашим плагином или для предотвращения отображения чего-либо вообще.
Вы добавляете фильтры в свой код, используя apply_filters()
, которую я вскоре продемонстрирую. Как указывает слово ‘apply’, вы применяете фильтры к существующему коду, тогда как действие, которое вы создаете с помощью do_action()
, пусто, пока вы не подключите к нему функции.
Использование функций, действий и фильтров
Давайте рассмотрим несколько примеров, демонстрирующих, как вы используете каждую из функций, действий и фильтров. Сначала мы рассмотрим использование функций непосредственно в вашем коде, не привязывая их к хуку.
Вызов функций напрямую
Вот пример функции, которая вызывается непосредственно в файле шаблона. На своих клиентских сайтах я добавляю колофон в нижний колонтитул, который включает информацию об авторских правах. Вот функция:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
if ( ! function_exists( ‘compass_colophon’ ) ) {
function compass_colophon() { ?>
<section class=»colophon» role=»contentinfo»>
<small class=»copyright left»>
<?php echo compass_copyright();
<a href=»<?php echo home_url( ‘/’ ) ?>» title=»<?php echo esc_attr( get_bloginfo( ‘name’, ‘display’ ) ); ?>» rel=»home»>
<?php bloginfo( ‘name’ );
</a>
</small><!— #copyright —>
<small class=»credits right»>
Powered by <a href=»http://wordpress.org/»>WordPress</a> and designed by <a href=»http://compass-design.co.uk»>Compass Design</a>.
</a>
</small><!— #credits —>
</section><!—#colophon—>
<?php }
}
|
Эта функция является подключаемой, поскольку я использую ее в родительской теме; если я затем создам новую функцию с тем же именем в моей дочерней теме, она переопределит эту функцию. Обратите внимание, что функция включает в себя другую функцию, compass_colophon()
, вызывающую ее непосредственно в коде.
Эта функция находится в файле functions.php
моей родительской темы. Я могу вызвать его прямо в файле моей темы footer.php
, например:
1
|
compass_colophon();
|
Это выводит код в функцию в той точке моей темы, где я ее называю. Вы также можете передавать параметры своим функциям, которые затем используются внутри функции.
Как я покажу в ближайшее время, эта функция также может быть связана с действием или фильтром.
Привязка функций к действиям
Вместо прямого вызова этой функции colophon у меня будет больше гибкости, если я присоединю ее к хуку.
Создание хуков действий
Вместо того, чтобы вызывать compass_colophon()
в моем файле compass_colophon()
колонтитула, я могу добавить ловушку действия в этой точке в файле footer.php
, добавив это:
1
|
do_action( ‘compass_in_footer’ );
|
Функция do_action()
имеет один обязательный параметр, который является именем действия. Вы также можете добавить аргументы к нему.
Привязка функций к действиям
Так что теперь вместо того, чтобы вызывать мою функцию colophon, мне нужно привязать ее к моей новой ловушке действия. В моем файле functions.php
я добавляю это с моей функцией:
1
|
add_action( ‘compass_in_footer’, ‘compass_colophon’ );
|
Это compass_in_footer
мою функцию к действию compass_in_footer
, что означает, что код внутри моей функции будет выполняться в той точке кода, где было размещено действие. Первый параметр — это имя хука действия, а второй — имя моей функции.
Преимущество такого способа состоит в том, что вы можете привязать более одной функции к одному действию и установить приоритет, чтобы они выполнялись в том порядке, в котором вы хотите.
compass_in_footer
, у меня есть еще одна функция, которую я хочу подключить к моей compass_in_footer
, которая называется compass_smallprint()
, которая содержит еще несколько маленьких compass_smallprint()
:
1
2
3
4
5
6
|
if ( ! function_exists( compass_smallprint() ) ) {
function compass_smallprint() {
// contents of function here
}
}
add_action( ‘compass_in_footer’, ‘compass_smallprint’, 20 );
|
Здесь вы можете видеть, что я добавил третий параметр в свою функцию add_action()
, который является приоритетом. Приоритет по умолчанию — 10
, который будет применяться, если вы оставите это поле пустым. Так как я не установил приоритет для моей функции compass_colophon()
, установка 20 для функции compass_smallprint()
заставит эту функцию работать после функции compass_colophon()
.
Отключение функций от действий
Иногда вы хотите остановить выполнение функции и не можете переопределить ее, потому что она не подключаема. Если функция подключена к remove_action()
действия, вы можете сделать это с помощью функции remove_action()
.
Поэтому, если я хочу запретить выполнение моей функции compass_smallprint()
, я отсоединяю ее от действия compass_in_footer
следующим образом:
1
|
remove_action( ‘compass_in_footer’, ‘compass_smallprint’, 20 );
|
Функция remove_action()
имеет три параметра: имя ловушки действия, имя функции и приоритет, с которым функция была первоначально привязана к действию. Вы должны указать приоритет, чтобы это работало.
Вы также можете отсоединить все функции от действия, если хотите запретить их выполнение. Будьте осторожны при этом, так как могут быть функции, о которых вы не знаете, подключенные к вашему действию.
Для этого используйте remove_all_actions()
:
1
|
remove_all_actions( ‘compass_in_footer’ );
|
Добавление номера приоритета в качестве второго параметра удаляет только те функции, которые подключены к этому крюку действий с указанным вами приоритетом, что дает вам больше контроля.
Привязка функций к фильтрам
У вас также есть возможность подключить свои функции к фильтрам. Вы делаете это, когда хотите изменить или переопределить существующий код. Когда вы создаете ловушку фильтра (используя apply_filters()
), вы оборачиваете ее вокруг кода в вашей теме или плагине, который затем изменяется любыми фильтрами, прикрепленными к ловушке.
Это может быть полезно, если у вас есть опции темы или плагина, которые вы хотите переопределить по умолчанию, или если вы создаете родительскую тему, в которой могут быть элементы, переопределенные дочерней темой.
Создание фильтров-хуков
Функция apply_filters()
имеет три параметра: имя ловушки фильтра, значение, которое вы хотите фильтровать (т. Е. Значение по умолчанию), и необязательные переменные, которые вы затем передаете функциям, подключенным к фильтру.
Вы можете добавить фильтр в файлы шаблона вашей темы или в функцию, которая подключается через ловушку действий. Давайте посмотрим на оба варианта.
Возвращаясь к моей функции compass_colophon()
, я преобразовываю это в фильтр, добавляя его содержимое в мой файл footer.php
внутри функции apply_filters()
следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
echo apply_filters( ‘compass_colophon’, ‘
<section class=»colophon» role=»contentinfo»>
<small class=»copyright left»>
<?php echo compass_copyright();
<a href=»<?php echo home_url( ‘/’ ) ?>» title=»<?php echo esc_attr( get_bloginfo( ‘name’, ‘display’ ) ); ?>» rel=»home»>
<?php bloginfo( ‘name’ );
</a>
</small><!— #copyright —>
<small class=»credits right»>
Powered by <a href=»http://wordpress.org/»>WordPress</a> and designed by <a href=»http://compass-design.co.uk»>Compass Design</a>.
</a>
</small><!— #credits —>
</section><!—#colophon—>’
);
|
Это выводит код, который я установил в качестве второго параметра моей функции apply_filters()
.
Однако я предпочитаю не добавлять это непосредственно в файл шаблона темы, поэтому я добавлю фильтр к функции, которую я уже присоединяю через ловушку действия.
Поэтому я добавляю действие compass_in_footer
в мой файл footer.php
используя do_action()
как показано выше, а затем я создаю функцию в своем файле functions.php
который подключается к этому действию и содержит фильтр:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
if ( ! function_exists( ‘compass_colophon’ ) ) {
function compass_colophon() {
echo apply_filters( ‘compass_colophon_filter’, ‘
<section class=»colophon» role=»contentinfo»>
<small class=»copyright left»>
<?php echo compass_copyright();
<a href=»<?php echo home_url( ‘/’ ) ?>» title=»<?php echo esc_attr( get_bloginfo( ‘name’, ‘display’ ) ); ?>» rel=»home»>
<?php bloginfo( ‘name’ );
</a>
</small><!— #copyright —>
<small class=»credits right»>
Powered by <a href=»http://wordpress.org/»>WordPress</a> and designed by <a href=»http://compass-design.co.uk»>Compass Design</a>.
</a>
</small><!— #credits —>
</section><!—#colophon—>’
);
}
add_action( ‘compass_in_footer’, ‘compass_colophon’ );
|
Это означает, что теперь я могу переопределить содержимое по умолчанию одним из трех способов:
- создав новую функцию под названием
compass_colophon()
в моей дочерней теме, которая переопределяет функцию в моей родительской теме, так как она подключаема -
compass_colophon()
функциюcompass_colophon()
отcompass_in_footer
действияcompass_in_footer
и написав новую функцию, которую я прикрепил к ней вместо нее - путем создания новой функции, которую я затем подключаю к
compass_colophon_filter
фильтраcompass_colophon_filter
, который переопределяет значение в моей функцииapply_filters()
В реальной жизни вам не нужно иметь столько опций, так что более вероятно, что вы примените фильтры к части контента в вашей функции, а не ко всему.
Таким образом, я мог бы создать два фильтра, один для раздела об авторских правах, а другой для кредитов:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
if ( ! function_exists( ‘compass_colophon’ ) ) {
function compass_colophon() {
echo ‘<section class=»colophon» role=»contentinfo»>’;
echo apply_filters( ‘compass_copyright_filter’, ‘
<small class=»copyright left»>
<?php echo compass_copyright();
<a href=»<?php echo home_url( ‘/’ ) ?>» title=»<?php echo esc_attr( get_bloginfo( ‘name’, ‘display’ ) ); ?>» rel=»home»>
<?php bloginfo( ‘name’ );
</a>
</small><!— #copyright —>’
);
echo apply_filters( ‘compass_copyright_filter’, ‘
<small class=»credits right»>
Powered by <a href=»http://wordpress.org/»>WordPress</a> and designed by <a href=»http://compass-design.co.uk»>Compass Design</a>.
</a>
</small><!— #credits —>’
);
echo ‘</section><!—#colophon—>’;
}
add_action( ‘compass_in_footer’, ‘compass_colophon’ );
|
Затем я мог бы либо переопределить всю мою функцию compass_colophon, отсоединив ее, либо написав новую в своей дочерней теме, или я мог бы создать функцию, подключенную к compass_copyright_filter
compass_credits_filter
compass_copyright_filter
или compass_credits_filter
, чтобы переопределить каждый элемент по отдельности.
Привязка функций к фильтрам
Чтобы add_filter()
функцию к перехватчику фильтра, вы используете add_filter()
, которая имеет два параметра: имя перехвата и имя функции.
Таким образом, чтобы изменить кредиты, я бы написал эту функцию:
1
2
3
4
5
6
7
|
function new_credits() { ?>
<small class=»credits right»>
Powered by <a href=»http://wordpress.org/»>WordPress</a> and designed by <a href=»http://rachelmccollin.co.uk»>Rachel McCollin</a>.
</a>
</small><!— #credits —>
<?php }
add_filter( ‘compass_credits_filter’, ‘new_credits’ );
|
Это переопределяет значение, установленное в моем исходном compass_credits_filter
фильтра compass_credits_filter
содержимым моей функции new_credits()
, но сохраняет все остальное в функции compass_colophon()
таким же.
Вы также можете указать приоритеты при подключении функций к фильтрам точно так же, как при подключении действий. Функции с более низким приоритетом будут запускаться первыми.
Отключение функций от фильтров
Как и в случае с хуками действий, вы также можете удалять функции из хуков фильтров. Это делается с помощью функции remove_filter () , которая имеет три параметра: имя ловушки фильтра, имя функции и приоритет, который является обязательным, если приоритет был установлен, когда функция была первоначально подключена к фильтру.
Таким образом, чтобы удалить мою new_credits()
, я использую это:
1
|
remove_filter( ‘compass_credits_filter’, ‘new_credits’ );
|
Вывод кода затем вернется к значению, указанному мной в моей исходной функции apply_filters()
. Поэтому, если бы я хотел удалить new_credits()
и на ее месте ничего не появлялось, мне пришлось бы добавить новую функцию. Затем я отцепил первую функцию и подключил свою новую функцию так:
1
2
3
4
5
|
function no_credits() {
return;
}
remove_filter( ‘compass_credits_filter’, ‘new_credits’ );
add_filter( ‘compass_credits_filter’, ‘no_credits’ );
|
Резюме
Понимание разницы между ловушками действий и фильтров и возможность их эффективного использования дадут толчок развитию вашей темы и плагинов. На самом деле, без использования перехватчиков хотя бы одного типа, вы вообще не можете писать плагины, поскольку единственный способ активировать код в ваших плагинах — через действие и перехватчики фильтров, к которым он прикреплен.
В этом руководстве показано, как добавить те же функции с помощью функции, ловушки действий и одной или нескольких ловушек фильтров, а также способы удаления функций из ловушек и советы о том, когда каждая техника более полезна.
Помимо привязки функций к вашим собственным действиям и фильтрам, которые вы создаете, вы можете подключить их к действиям и фильтрам, предоставляемым WordPress, таким как действие wp_head
или фильтр body_class
.