Статьи

Копаем глубже в WordPress Хуки и Фильтры

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

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

баннер для WordPress

Вообще говоря, плагины и темы, с которыми вы будете работать, будут основаны на методах объектно-ориентированного проектирования , где один или несколько классов определяют, как работает эта функциональность. Внутри этих классов они могут определять хуки, которые вы хотите полностью удалить или заменить своими собственными пользовательскими функциями.

Сегодня собирались разобраться в хуках WordPress и о том, как вы можете справиться с ними как в традиционном смысле, так и при работе с классами или объектами.

Удаление стандартных крючков

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

  • $tag — Имя хука, к которому прикреплена функция.
  • $function_to_remove — имя функции, которая должна быть удалена.
  • $priority — приоритет функции, когда она была присоединена к хуку.

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

Пример 1: Стандартный WooCommerce Hook

Давайте посмотрим на визуальный пример. Рассмотрим плагин WooCommerce. Когда вы находитесь на одной странице (используя шаблон single-product ), вы по умолчанию увидите панель навигации.

Базовый WordPress хук WooCommerce

Это выводится через do_action( 'woocommerce_before_main_content' ); крюк. Его целью является вывод начального содержимого оболочки и панировочных сухарей для продукта.

WooCommerce крючок фото

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

 //remove breadcrumbs from single product remove_action('woocommerce_before_main_content', 'woocommerce_breadcrumb', 20); 

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

основной хук WooCommerce удален

Удаление крючков, добавленных в классы

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

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

 //remove a hooked function from within a call function('hook_name', array($myclass, 'my_function_remove'), 10); 

Так где же находится объект класса?

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

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

$myClassObject = MyClass::getInstance()

Если у класса нет такого метода, вы можете попытаться получить объект, вызвав его глобально, например:

global $myClassObject

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

Если вы пытаетесь удалить выводимые визуальные элементы, вы сможете проследить, откуда все это происходит, например:

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

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

Пример 1: Крючок внутри класса WooCommerce

Давайте посмотрим на практический пример, чтобы вы могли увидеть, как вы примените эту технику.

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

скриншот продвинутого класса

При отображении электронной почты WordPress woocommerce_email_customer_details хук woocommerce_email_customer_details и активирует все функции, связанные с ним. Когда это происходит, запускается функция customer_details определенная в классе WC_Emails с WC_Emails о клиенте.

расширенные детали крюка класса

Если бы мы не хотели отображать эти детали, нам пришлось бы удалить функцию customer_details из класса.

К счастью, в нижней части конструктора находится действие woocommerce_emails , которое do_action с помощью do_action . Мы можем зацепить там, чтобы мы могли удалить данные наших клиентов. Этот хук передается самому объекту через $this поэтому он идеально подходит для наших нужд.

 //Remove email details from the `WC_Emails` class function remove_customer_email_details($instance) { //remove `customer_details` hooked function remove_action('woocommerce_email_customer_details', array( $instance, 'customer_details'), 10); } add_action('woocommerce_email', 'remove_customer_email_details'); 

Мы вызываем remove_action и передаем как функцию $instance и функцию customer_details и когда мы просматриваем наши электронные письма, сведения о клиенте исчезают, полностью удаляются.

удаленные детали крюка продвинутого класса удалены

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

Пример 2: зацепка внутри пользовательского класса

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

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

ПРИМЕЧАНИЕ. Полезно указать, что remove_filter — это то же самое, что и remove_action . В конце концов, все они — путь к удаленной подключенной функции, и WordPress рад, что вы можете использовать их взаимозаменяемо.

 //A simple test class, loaded directly in your website //Loaded from the parent theme class testClass{ //magic constructor public function __construct(){ add_filter('the_title', array($this, 'wrapTitle'), 10, 1); add_filter('add_extra_word', array($this, 'output_word'), 10, 1); } //wrap the title for each post public function wrapTitle($title){ $html = ''; $html .= '<div class="titleWrap">'; $html .= $title; //append a word to the end of the title $html = apply_filters('add_extra_word', $title); $html .= '</div>'; return $html; } //append the word 'Hello World' to the end of the title public function output_word($title){ $html = ''; $html = $title . ' <strong>Hello World</strong>'; return $html; } } $testclass = new testClass(); 

Этот класс добавляет функцию wrapTitle на хук the_title прямо в методе _construct . Это означает, что как только класс будет загружен, он подключит эту функцию к заголовку и будет вызываться каждый раз, когда мы показываем сообщение. Внутри функции wrapTitle она оборачивает текущий заголовок вокруг div и затем вызывает фильтр add_extra_word .

Вернувшись в конструктор, мы подключили еще одну функцию с именем output_word к фильтру add_extra_word . Цель этой функции — добавить текст Hello World, выделенный жирным шрифтом, в конец заголовка.

подключить пример два перед

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

 //removes the extra word appended to the title (added by the class) //Added to your child theme function remove_extra_word(){ global $testclass; remove_filter('add_extra_word', array($testclass, 'output_word'), 10); } add_action('init', 'remove_extra_word'); 

Сначала мы подключаем нашу функцию для загрузки в init . Причина, по которой мы делаем это, а не просто выполняем remove_filter прямо в файле PHP, заключается в том, что мы хотим, чтобы он запускался только после начала загрузки WordPress. Если бы мы объявили эту функцию еще до того, как класс был загружен, она бы ничего не делала (так как класс должен существовать первым).

Мы global $testclass копию класса с помощью global $testclass . Мы делаем это, потому что у этого класса не было никакого способа дать нам наш объект напрямую.

Внутри функции мы теперь используем функцию remove_filter и удаляем функцию output_word прикрепленную к действию add_extra_word определенному в нашем классе.

Когда все это будет сделано и очищено, текст Hello World будет удален, и ваши заголовки вернутся к норме.

подключить пример два после

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

Где эта техника не будет работать

Если вы вообще не можете найти объект класса (либо переданный в качестве переменной в хуке, либо через какой-либо другой метод), то эта методика потерпит неудачу. Основная часть принципалов объектно-ориентированного проектирования говорит, что всегда должна быть ссылка на объект, чтобы к нему можно было получить доступ, или если нет, это простой способ загрузить объект.

Если это произойдет, вы можете попробовать следующие шаги (каждый более решительный и менее рекомендуемый, когда мы идем вниз):

  • Свяжитесь с разработчиком темы или плагина и попросите дополнительные хуки.
    • Большинство разработчиков очень хотят помочь людям, поэтому это хорошее место для начала. Когда они обновляют свой плагин или тему, вы должны иметь возможность беспрепятственного обновления (если оно настроено правильно).
  • Измените свой плагин или вашу тему.
    • Если это не работает для вас, посмотрите, есть ли что-нибудь еще, что могло бы обеспечить лучшую функциональность и быть более дружественным для разработчика.
  • Вручную отредактируйте свой плагин или тему напрямую.
    • Если вам нужно придерживаться своего плагина или темы и вам отчаянно нужно изменить способ его работы, то вы всегда можете редактировать файлы напрямую. Вообще говоря, это ужасное предложение, так как любые сделанные вами изменения будут потеряны, если вы когда-нибудь обновите свою тему или плагин. Однако иногда вам просто нужно решить проблему.

Завершение всего этого

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

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

Для дальнейшего изучения системы ловушек WordPress , ознакомьтесь с разделом « Система ловушек WordPress» от Agbonghama Collins.