Сегодня мы поговорим о системе хуков в WordPress. Мы рассмотрим хуки действий и фильтры, и их роль в развитии WordPress.
Эти оба вида хуков играют особую роль в развитии WordPress. Если вы хотите стать опытным разработчиком WordPress, то нужно не только понимать разницу между этими хуками, но и уметь их применять.
Мы уже рассказывали вам о том, что такое хуки и как их можно использовать. Но перед тем, как мы начнём нашу сегодняшнюю тему, давайте вспомним, что мы обсуждали в прошлой статье.
Смотрите также:
- Добавление кастомных хуков в WordPress: Custom Actions
- Советы для начинающих разработку сайта на WordPress
- Руководство по кастомным типам записей WordPress
- Custom Post Types: пользовательские таксономии, фильтры и архивы в WordPress
- Что такое Форматы постов в WordPress и для чего они нужны
- Что следует знать о форматах постов в WordPress
Приступим!
Освежим в памяти
В предыдущей статье на эту тему мы увидели, как хуки являются внедрением событийно-ориентированной архитектуры. Мы выделили несколько моментов:
- У программного обеспечения есть несколько моментов, когда оно передаёт сообщения, что что-то произошло.
- Мы, как разработчики, можем написать код, который будет принимать эти сообщения и отвечать на них с пользовательским кодом.
И потом на примере контента мы увидели, как именно это действует на WordPress. Мы рассказали о его преимуществах и о внедрении собственных хуков действия.
К тому же, мы узнали о тонком различии:
Хуки действий предназначены для работы с функциональностью, а фильтры – с данными.
В то время, как действия позволяют нам менять чьё-то поведение, фильтры же позволяют нам менять данные до их сохранения, проверки или отображения на экране. В этой статье мы рассмотрим, как работать с фильтрами до вывода данных на экран, например, написание текста строчными буквами или удаление гласных из текста.
До того, как мы начнём, нужно убедиться, что наша среда разработки настроена и готова к работе.
Приступим
Вспомним из нашей предыдущей статьи, что наша среда разработки должна иметь в составе:
- wordpress
- Веб-сервер
- Копия PHP
- База данных
В основном Apache, PHP и MySQL можно установить легко. Если вы уже опытный пользователь, то можете использовать что-то типа Nginx и альтернативную базу данных. Если это так – прекрасно, но в этом руководстве мы будем использовать наш начальный список.
Понимание фильтров в WordPress
WordPress Codex предоставляет полный набор ресурсов для тех, кто хочет узнать всё о фильтрах. Как мы уже говорили, он даёт такое определение фильтрам:
Пользовательские Фильтры отличаются от пользовательских Действий, поскольку пользовательские Действия позволяют вам добавить или удалить код из существующих Действий. А пользовательские Фильтры позволяют вам заменить конкретные данные (например, переменную), находящиеся в существующем Действии.
Но если вам интересен весь список доступных фильтров на WordPress, то обязательно посетите эту страницу в Codex. У многих фильтров есть ссылка на собственную страницу с документацией.
Это значит, что если вы ищете фильтр с какими-то конкретными функциями, то вам стоит зайти на эту страницу. А чтобы узнать о примерах применения фильтра, стоит зайти в его документацию.
Немного о приоритетах и параметрах
Перед тем, как мы пойдём дальше, мы хотим убедится, что все мы находимся на одной и той же странице, с одинаковым приоритетом и количеством аргументов, когда мы говорим о них в контексте хуков WordPress.
Как пример можно использовать следующую строку кода:
add_filter( 'author_edit_pre', 'filter_function_name', 10, 2 );
Это говорит нам о 4 вещах:
- Имя фильтра – это то, к чему мы подсоединяемся
- Имя функции – это то, что должно быть вызвано
- Приоритет, когда функция должна быть вызвана
- Количество параметров, которые должна принять функция
Первые два пункта вполне понятны, а два последних могут сбить с толку начинающих разработчиков, но на самом деле, это не так уж и сложно.
Во-первых, думайте о приоритете, как о времени, когда нужно вызвать функцию. Помните, что у хука может быть несколько функций, а приоритет позволяет вам определить время для вызова каждой функции. Чем меньше количество, тем быстрее их запустят, чем больше количество, там позже их запустят.
Во-вторых, число указывает на количество параметров, которые должен принять аргумент. Если вы не укажете число, то он либо не примет ни одного параметра, либо использует число по умолчанию. Если вы хотите передать другое количество параметров, то вы должны это указать. Мы рассмотрим это более детально немного позже.
Работа с фильтрами
Перед началом работы с фильтрами, давайте создадим собственный файл в корне директории темы Twenty Sixteen. Мы назовём файл tutsplus-filters.php. А в файл functions.php мы добавим следующую строчку кода:
include_once( get_template_directory() . '/tutsplus-filters.php' );
Это позволит убедиться, что весь наш пользовательский код будет находиться в одном файле, который мы можем удалить.
Фильтрация контента поста
Перед началом создания собственных пользовательских фильтров, важно понять, как они работают. Поскольку фильтры предназначены для изменения данных, а записи являются единственными строительными блоками блога, то давайте сначала посмотрим, как мы можем фильтровать контент записи блога до его отображения на экране.
Это похоже на принцип работы хуков действий WordPress, но тут меняются данные, а не поведение.
1. Регистрация нашего фильтра
Для регистрации нашего фильтра необходимо знать 2 вещи:
- Название фильтра, к которому мы присоединим наше действие
- Функцию, которая будет отвечать за фильтр данных
Так как мы собираемся изменить контент записи, то мы можем использовать фильтр the_content. Суть функции заключается в следующем — Она принимает один аргумент, контент записи, позволяет нам поменять его, и потом возвращает его посетителю.
В этом случае WordPress передает контент записи функции, а потом функция вернет данные после того, как закончит свою работу.
Давайте назовём нашу пользовательскую функцию tutsplus_the_content, а потом зарегистрируем её на WordPress.
add_filter( 'the_content', 'tutsplus_the_content' ); function tutsplus_the_content( $content ) { return $content; }
Примерно так должна выглядеть функция. Конечно, она не делает очень много. Просто возвращает контент, который передаётся на неё.
2. Изменение контента
Давайте заставим функцию немного изменить данные. Для этого нужно:
- Убедится, что запись можно посмотреть в отдельном окне
- Добавить сообщение вверх записи, где сообщается, что контент записи был изменён
Это не лучший способ использовать фильтр, но зато вы поймёте, как вы можете менять функцию.
Вот так должен выглядеть код. Обратите внимание на комментарии в коде:
add_filter( 'the_content', 'tutsplus_the_content' ); function tutsplus_the_content( $content ) { // Don't proceed with this function if we're not viewing a single post. if ( ! is_single() ) { return $content; } // First, define the message to be displayed. $html .= '<p>'; $html .= 'This is a custom message created by a hooked function.'; $html .= '</p>'; // Now prepend it to the content. $content = $html .= $content; return $content; }
Если вы посмотрите на основную страницу блога, то все посты будут выглядеть стандартно, без изменений. Но если вы зайдете отдельно на страницу записи, то увидите, что вверху появилась новая фраза:
This is a custom message created by a hooked function.
А теперь давайте сделаем что-то более продвинутое. Давайте удалим все гласные из контента поста. Прежде чем вернём его на WordPress.
Для этого используем следующий код:
add_filter( 'the_content', 'tutsplus_the_content' ); function tutsplus_the_content( $content ) { // Don't proceed with this function if we're not viewing a single post. if ( ! is_single() ) { return $content; } // First, remove all of the vowels from the content using a regular expression. $content = preg_replace( '$[aeiou]$i', '', $content ); // Then, define the message to be displayed. $html .= '<p>'; $html .= 'This is a custom message created by a hooked function.'; $html .= '</p>'; // And now prepend it to the content. $content = $html .= $content; return $content; }
Вставив код, сохраните изменения и зайдите на любую запись в WordPress.
Технически, функция наверху выполняет 2 вещи, поэтому для улучшения кода мы рекомендуем разделить её на 2 отдельные функции, а наша главная функция фильтра будет вызывать их.
Вот так будет выглядеть финальный результат:
add_filter( 'the_content', 'tutsplus_the_content' ); function tutsplus_the_content( $content ) { // Don't proceed with this function if we're not viewing a single post. if ( ! is_single() ) { return $content; } $content = _tutsplus_strip_vowels( $content ); $content = _tutsplus_add_message( $content ); return $content; } function _tutsplus_strip_vowels( $content ) { return preg_replace( '$[aeiou]$i', '', $content ); } function _tutsplus_add_message( $content ) { $html .= '<p>'; $html .= 'This is a custom message created by a hooked function.'; $html .= '</p>'; return ( $html . $content ); }
И снова, внедрение фильтра – это не самое практичное и полезное, что вы можете сделать, но это показывает, что мы можем делать, когда настраиваем наши собственные функции.
Определение пользовательских фильтров
Легко использовать уже существующие фильтры. Как мы уже говорили ранее, очень легко вызвать add_filter, указав название фильтра, а затем название функции, которую мы хотим вызвать для фильтра данных.
Но что если мы хотим создать наш собственный фильтр? Наверное, мы хотим создать фильтр, который сделает все буквы в нашем посте строчными? Или фильтр, который удалит все гласные из записи?
Понимание apply_filters
И вот тут мы начинаем интересоваться apply_filters. Эта конкретная функция принимает 2 аргумента:
- тэг, который определяет название хука фильтра
- значение, которое относится к значению применения фильтра
Примером может послужить get_the_content в ядре WordPress, вы можете заметить, что он передает особое значение the_content_more_link через apply_filters.
Это полезно знать, но как же нам определить наш собственный пользовательский фильтр, который все смогут применить через apply_filters?
Добавление наших собственных фильтров
Добавить наши собственные фильтры легко. Нам нужно определить те же 4 вещи, которые мы описали выше:
- Название фильтра
- Функцию, которую должен вызвать фильтр
- Приоритет функции
- Количество аргументов, которых он должен принять
Давайте начнём с простого примера.
Сделать все буквы строчными
Во-первых, мы хотим дать фильтру приоритет 10. Мы знаем, что он примет всего один аргумент, контент, поэтому мы пропустим номер 1 при добавлении фильтра:
add_filter( 'tutsplus_lowercase_all', 'tutsplus_lowercase_all_callback', 10, 1 );
Далее мы определим тело простой функции, которая использует функцию PHP strtolower для понижения регистра, не важно при этом, какое значение было передано, и возвращаем её.
function tutsplus_lowercase_all_callback( $content ) { return strtolower( $content ); }
Конечная версия кода будет выглядеть так:
add_filter( 'tutsplus_lowercase_all', 'tutsplus_lowercase_all_callback', 10, 1 ); function tutsplus_lowercase_all_callback( $content ) { return strtolower( $content ); } add_filter( 'the_content', 'tutsplus_the_content' ); function tutsplus_the_content( $content ) { // Don't proceed with this function if we're not viewing a single post. if ( ! is_single() ) { return $content; } return apply_filters( 'tutsplus_lowercase_all', $content ); }
Довольно просто, правда? Давайте теперь взглянем на ещё один пример, базирующийся на функционале, который мы уже описали.
Удаление всех гласных
Для удаления всех гласных мы можем использовать ту же функцию, которую мы уже определили. Однако, нам нужно изменить способ регистрации фильтра на WordPress, а потом нужно убедиться, что функция, зарегистрированная на WordPress, правильно вызывает apply_filters.
Теперь мы знаем, как добавлять наш собственный фильтр, определять приоритет, называть количество аргументов, которые он должен принять, и применять функцию.
Вот фильтр, который вызывается сам по себе:
add_filter( 'tutsplus_remove_vowels', 'tutsplus_remove_vowels_callback', 10, 1 ); function tutsplus_remove_vowels_callback( $content ) { return preg_replace( '$[aeiou]$i', '', $content ); } add_filter( 'the_content', 'tutsplus_the_content' ); function tutsplus_the_content( $content ) { // Don't proceed with this function if we're not viewing a single post. if ( ! is_single() ) { return $content; } return apply_filters( 'tutsplus_remove_vowels', $content ); }
Вызов всех фильтров вместе
Наконец, можно вызывать apply_filters много раз:
add_filter( 'tutsplus_remove_vowels', 'tutsplus_remove_vowels_callback', 10, 1 ); function tutsplus_remove_vowels_callback( $content ) { return preg_replace( '$[aeiou]$i', '', $content ); } add_filter( 'tutsplus_lowercase_all', 'tutsplus_lowercase_all_callback', 10, 1 ); function tutsplus_lowercase_all_callback( $content ) { return strtolower( $content ); } add_filter( 'the_content', 'tutsplus_the_content' ); function tutsplus_the_content( $content ) { // Don't proceed with this function if we're not viewing a single post. if ( ! is_single() ) { return $content; } return apply_filters( 'tutsplus_lowercase_all', apply_filters( 'tutsplus_remove_vowels', $content ) ); }
Заметьте, что это достигает тех же результатов, что и предыдущий пример. Есть еще и другие способы, но целью данного руководства было научить вас, как написать собственный фильтр и как применить apply_filters в вашей работе.
Итоги
Система хуков – это один из мощнейших аспектов WordPress для разработчиков. Вы теперь можете не только управлять поведением и данными WordPress, но и в состоянии самостоятельно определить хуки, которые потом смогут использовать и другие разработчики.
Не бойтесь экспериментировать с кодом, который мы вам предоставили.
Комментарии к записи: 1
Отличный пост. Чуть чуть поправлю по коду, перед конкатенацией строк с переменной $html, её нужно сначала определить, то есть изначально она к примеру пуста $html = «». то важно, так как если есть условие и переменная не определена, то можно получить маленькую ошибку в виде нотиса