Статьи

Действия и фильтры WordPress: в чем разница?

Хуки действий и фильтров являются фундаментальной частью различных API WordPress. Без них вы ограничены тем, что вы можете делать в своих темах и (особенно) в своих плагинах.

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

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

Когда вы добавляете хуки действий и фильтров к своему коду (или вы привязываете к ним функции), это помогает понять, как WordPress вызывает действия и фильтры и что происходит в каком порядке. Я не буду подробно останавливаться на этом здесь, так как у нас есть другой учебник, который выполняет эту работу.

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

Функции — это первое, с чем большинство людей работают, изучая разработку WordPress; если вы добавили код в файл functions.php вашей темы, то вы написали функцию.

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

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

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

Вы можете добавить свои собственные 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 .