Add filter


add_filter (string $tag, callable$ function_to_add, int $priority = 10, int$ accepted_args = 1)  

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

WordPress предлагает фильтры, позволяющие плагинам изменять различные типы внутренних данных во время выполнения.

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

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

Обратите внимание, что $примера передается функция обратного вызова, (может быть) изменено, а затем вернулся:

function example_callback($ example) {   // Maybe modify $example in some way.   return$ example;  }  add_filter('example_filter', 'example_callback');  

Связанных функции обратного вызова могут принимать от нуля до общего количества аргументов, переданных в качестве параметров в соответствующем apply_filters()


вызова ,

Другими словами, если вызов apply_filters() передает четыре общих аргумента, обратные вызовы, связанные с , он не может принимать ни одно (то же, что и 1) аргументов, либо до четырех. Важная часть состоит в том, что значение $accepted_args должно отражать количество аргументов, которые связанный обратный вызов фактически решил принять. Если никакие аргументы не были приняты обратным вызовом, который считается таким же, как прием 1 аргумента. Например:

// Filter call.$ value = apply_filters('hook', $value,$ arg2, $arg3);   // Accepting zero/one arguments.  function example_callback(){   ...   return 'some value';  } add_filter('hook', 'example_callback'); // Where$ priority is default 10, $accepted_args is default 1.   // Accepting two arguments (three possible).  function example_callback($ value, $arg2){   ...   return$ maybe_modified_value;  }  add_filter('hook', 'example_callback', 10, 2); // Where $priority is 10,$ accepted_args is 2.  

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

wordpress.stackovernet.com

Большинство из приведенных ниже можно найти в Codex :


apply_filters

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

 $value = apply_filters( $tag, $value, $var_1, $var_2, ... );  

По существу:
Вы используете apply_filters для фильтрации данного $value – по отношению к самому значению, а также необязательно предоставленные переменные $var_1 через $var_n .


add_filter

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

 add_filter( $tag, $function_to_add, $priority, $accepted_args );  

По существу:
Вы используете add_filter для add_filter пользовательской функции к данному действию фильтра ( $tag ), который раньше вы могли сгенерировать с помощью apply_filters (или это было встроенное действие фильтра или проистекало из плагина / вашей темы).



Итак, вот вымышленный пример:

 function print_initials( $name ) { if ( ! is_string( $name ) ) { return; } $fragments = explode( ' ', $name ); /** * Filter wether to print initials in reverse order. * * @param bool $reverse Print initials in reverse order? */ if ( apply_filters( 'reverse_initials', FALSE ) ) { $fragments = array_reverse( $fragments ); } foreach ( $fragments as $f ) { echo substr( $f, 0, 1 ); } } print_initials( 'Some Guy' ); // outputs: SG add_filter( 'reverse_initials', '__return_true' ); print_initials( 'Some Guy' ); // outputs: GS 

Теперь, если мы просто вызываем нашу функцию как есть, .


438;е по умолчанию.

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

www.wordpressask.com


add_filter() является вспомогательной функцией apply_filters(). Прежде чем apply_filters будет запущен для определенного фильтра (аргумент $tag в add_filter()), вы можете использовать add_filter для регистрации фильтра для тега. Когда apply_filters() выполняется с этим именем тега, он вызывает все зарегистрированные фильтры в порядке. Фильтры используются для передачи данных через функции манипуляции. Например, я часто использую фильтр wp_list_pages. Я использую его для удаления разрывов строк из списка страниц. Итак, как это работает:

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

function my_list_pages_filter($pages){  $pages = preg_replace( array("n","r"), '', $pages );  return $pages; } 

Затем я добавляю крючок фильтра: add_filter (‘wp_list_pages’, ‘my_list_pages_filter’);

add_filter


сообщает WordPress «Когда вызывается функция apply_filters с первым аргументом» wp_list_pages «, вызовите my_list_pages_filter«. Фильтры должны отправлять хотя бы одно значение (любого типа: string, array, integer и т.д.), И они ожидают, что функция вернет одно значение.

Они предоставляют вам способ управления вводом перед отправкой.

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

<div id="content" <?php $class='post post_content'; echo apply_filters('my_custom_classes', $class); ?>> 

И затем в файле functions.php добавьте следующее:

add_filter('my_custom_classes','my_custom_classes_function'); function my_custom_classes_function($classes){  $output 'class="'. $classes.'"';  return $output; } 

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

function my_custom_classes_function($classes){  $classes = explode( ' ', $classes );  if(is_home())  $classes[] = 'home_content';  if(is_single())  $classes[] = 'single_content';  if(is_page())  $classes[] = 'page_content';  if(is_tag())  $classes[] = 'tag_content';  $output 'class="'. implode( ' ', $classes ) .'"';  return $output; }   

qaru.site

Примеры

Добавим произвольную строку в конце всех заголовков постов

Вряд ли это может вам понадобиться, но такой вот простой пример.

Множество других примеров на truemisha.ru

Прежде всего я рекомендую вам почитать полное руководство по фильтрам в WordPress.

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

misha.blog

Что такое WordPress — фильтр

В Кодексе WordPress фильтрам дано следующее определение:

Итак, фильтр это функция на php, которая записывается в стек вызовов встроенной системы фильтров WordPress. Но в себе она может содержать сторонние функции и другие конструкции. Фильтр является одним из двух видов хуков (hooks) в WordPress. Второй — действие (action), но это предмет для другой серии статей.

Возможно, эта тема покажется вам сложной, но фильтры (как и действия) очень легко понять. Вначале моего знакомства с этими понятиями мне самому показалось все довольно сложным и запутанным, но, увидев, насколько они просты, я познакомился с сотнями фильтров и действий, просто изучая кодекс WordPress или копаясь в исходном коде. Определенно, вам также стоит узнать о сотнях фильтров. Но для начала вы должны научиться их использовать.


Используем фильтры в WordPress

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

В этой статье мы собираемся проделать четыре вещи:

  • Создадим функцию фильтра;
  • Сделать из нее хук;
  • Убрать функцию из фильтра;
  • Создать свой собственный фильтр.

Создаем функцию и прикрепляем ее к фильтру

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

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

Сложно? На самом деле, нет. В приведенном ниже примере, мы напишем код функции, которая удаляет гласные во всем тексте:

Функция берет строку заголовка $title, удаляет гласные и возвращает строку. Довольно просто, верно? Теперь прыгнем на уровень выше, сделаем хук, и прицепим его к фильтру:

Заметили новую функцию? Взглянем на add_filter():

  • $tag (обязательный параметр) – имя фильтра;
  • $function_to_add (обязательный параметр) – имя функции для хука;
  • $priority (опция) – Целое число для определения момента исполнения функции. По умолчанию равно 10: Функция сработает раньше, если вы снизите значение, и позже, если вы повысите его;
  • $accepted_args (опция) — Значение, нужное чтобы определить количество аргументов, которые пропускает фильтр. Значение по умолчанию равно1.

Удаляем фильтр

Конечно же, мы также можем убрать функцию, прикрепленную к фильтру. Для этого используем функцию remove_filter(). И смотрим, как она работает:

Параметры такие же, как и в случае с add_filter():

  • $tag (обязательный параметр) – имя фильтра;
  • $function_to_remove (обязательный параметр) – имя функции для удаления;
  • $priority (опция) — приоритет функции (определено при первом подключении функции).

Еще одна функция, remove_all_filters(), у которой всего лишь два параметра ($tag и $priority), в которых указываются имя функции и приоритет. Имя функции говорит само за себя. Она отключает все функции, прицепленные к фильтру.

Создаем свой собственный фильтр

Хотите знать, как создаются фильтры? Для этого существует специальная функция apply_filters(), находящаяся в ядре. Конечно же, ее можно использовать и вне ядра, и это означает то, что мы можем создавать фильтры внутри наших плагинов.
Посмотрим, как это работает на практике:

  • $tag (обязательный параметр) – имя привязываемой функции;
  • $value (обязательный параметр) — значение, которое будет меняться функцией, подключенной к фильтру через add_filter();
  • $var1, $var2 и так далее (опционально) – параметры фильтра (столько, сколько потребуется). Функция фильтра может использовать эти параметры, но они не смогут быть возвращены функциями.

Подумаем над таким примером: Представьте, что вы пишите функцию, которая возвращает только известную цитату Питера Гриффина:

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

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

Теперь, каждый раз, когда будет вызвана функция peter_griffin_quote(), цитата Питера будет слегка видоизменяться, при этом код плагина останется неизменным. Отлично!

Заключение

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

  • login_errors;
  • comment_post_redirect;
  • allowed_redirect_hosts;
  • body_class;
  • locale;
  • sanitize_user;
  • the_content;
  • the_password_form;
  • the_terms;
  • wp_mail_from.

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

И если вам понравилось то, что вы читаете в этой статье, не забудьте поделиться ею!

Увидимся на следующем уроке!

Перевод статьи “50 Filters of WordPress: An Introduction to Filters” был подготовлен дружной командой проекта Сайтостроение от А до Я.

www.internet-technologies.ru

Is it possible to add this filter

add_filter("the_content", "magicalender_get_event_page");

But only for one specific page, for example

if($post->post_name == "magicalenderpage")

If I put the if statement inside the function, then on any other pages the content isn’t displayed — and with an else statement afterwards that echoes out the content of the page otherwise I encounter problems where it interferes with other plug-ins that also do things with

add_filter("the_content", "foo");

The magicalender_get_event_page function is as follows

function magicalender_get_event_page(){  global $wpdb;  global $post;   if($post->post_name == "magicalenderpage"){  echo "<div class="magi_calender">";  for($i = 0; $event = $wpdb->get_row("SELECT * FROM ".$wpdb->prefix."magicalender", ARRAY_A, $i); $i++){  echo"  <div class="event">  <h1>".$event['event']."</h1>  <h2>".date('m/d/Y', strtotime($event['dmy']))."</h2>  <div>".str_replace("&amp;", "&", str_replace("&#39;", "'", str_replace("&#34;", """, $event['desc'])))."</div>  </div>  ";  }  echo "</div>";   $o = $wpdb->get_row("SELECT * FROM ".$wpdb->prefix."magioptions", ARRAY_A);  echo"  <script type="text/javascript">  var priority = '".$o['dm']."';  var customDays = new Array('".$o['monday']."', '".$o['tuesday']."', '".$o['wednesday']."', '".$o['thursday']."', '".$o['friday']."', '".$o['saturday']."', '".$o['sunday']."');  var customMonths = new Array('".$o['january']."', '".$o['february']."', '".$o['march']."', '".$o['april']."', '".$o['may']."', '".$o['june']."', '".$o['july']."', '".$o['august']."', '".$o['september']."', '".$o['october']."', '".$o['november']."', '".$o['december']."');  var customMonthsShort = new Array('".$o['jan']."', '".$o['feb']."', '".$o['mar']."', '".$o['apr']."', '".$o['ma']."', '".$o['jun']."', '".$o['jul']."', '".$o['aug']."', '".$o['sep']."', '".$o['oct']."', '".$o['nov']."', '".$o['dec']."');  jQuery(".magi_calender").magiCalender(priority, customDays, customMonths, customMonthsShort);  </script>  ";  }  else{  return $content;  } } 

wordpress.stackexchange.com

События

События или действия (actions) в WordPress очень похожи на события в JavaScript. Событие выполняется вызовом функции do_action(), а добавить функцию к любому событию можно с помощью функции add_action().

При выполнении события или действия, выполняются все функции, добавленные к событию в определенном порядке. Это легче всего понять с помощью простого примера. Определяем три функции, которые будут выводить 1, 2 и 3 соответственно:

function one() { echo 1; }  function two() { echo 2; }  function three() { echo 3; }  

Добавляем функции к событию foo с помощью функции add_action():

add_action( 'foo', 'one' );  add_action( 'foo', 'two' );  add_action( 'foo', 'three' );  

И выполняем наше событие с помощью функции do_action():

do_action( 'foo' ); // выведет 123  

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

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

Итак, наш пример вызовет функции one(), two() и three() по порядку, что выведет на экран 123. Конечно мы могли самостоятельно вызвать эти функции в этом же порядке на месте do_action(), что дало бы тот же самый результат. Так зачем использовать события?

Зачем использовать события

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

/* В другом плагине */  function four() { echo 4; }    remove_action( 'foo', 'three' );  add_action( 'foo', 'four' );  

Таким образом, когда дело дойдет до вызова события foo в вашем плагине, на экран выведется уже не 123, а 124, поскольку другой плагин удалил функцию three() из вашего события с помощью функции remove_action(), и добавил на ее место новую функцию four().

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

  • Ваша тема может выполнить событие в момент вывода шапки, и любой плагин сможет вывести на этом месте баннер, не изменяя код вашей темы
  • Ваша тема может выполнить событие в подвале, и с помощью плагина можно будет вставить в подвал любой текст
  • Ваш плагин выводит блок «поделиться» в конце каждой статьи, другой плагин сможет добавить новую социальную сеть в этот же блок

Стоит так же отметить, что в самом ядре WordPress есть более 1500 фильтров и событий, которые можно использовать в темах и плагинах.

Фильтры

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

function plus_one( $value ) {   $value = $value + 1;   return $value;  }  

Эта функция принимает один аргумент, добавляет к нему единицу и возвращает результат. Добавим нашу функцию к новому фильтру с помощью add_filter():

add_filter( 'foo', 'plus_one' );  

Теперь все функции добавленные к фильтру foo (в нашем случае это всего одна функция) можно легко вызвать или «применить» с помощью функции apply_filters():

echo apply_filters( 'foo', 5 ); // 6  

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

В данном случае на экран выведется значение 6, поскольку значение 5 было пропущено через функцию plus_one(), которая изменила оригинальную переменную. Если убрать функцию у фильтра с помощью remove_filter(), то наш код выведет первоначальное значение 5:

remove_filter( 'foo', 'plus_one' );  echo apply_filters( 'foo', 5 ); // 5  

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

Пример хорошего фильтра

Рассмотрим более интересный пример: создадим массив, который будет содержать ссылки на наши профили в социальных сетях и выводить эти ссылки в шапке нашей темы WordPress. В functions.php:

function get_my_social_profiles() {   $profiles = array(   'twitter' => 'http://twitter.com/wpmagru',   'facebook' => 'http://facebook.com/wpmagru',   );   return $profiles;  }

Возвращаемый массив можно использовать в цикле в нашем файле header.php:

$profiles = get_my_social_profiles();  foreach ( $profiles as $service => $url ) {   printf( '<a href="%s">%s</a>', esc_url( $url ), $service );  }  

Данный код выведет ссылки на Twitter и Facebook в шапке нашей темы. Для того чтобы добавить новую ссылку в список, нам придется изменять саму тему, или же создать новый фильтр в функции get_my_social_profiles():

/* В functions.php */  function get_my_social_profiles() {   $profiles = array(   'twitter' => 'http://twitter.com/wpmagru',   'facebook' => 'http://facebook.com/wpmagru',   );   return apply_filters( 'my_social_profiles', $profiles );  }

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

function change_my_social_profiles( $profiles ) {   unset( $profiles['twitter'] );   $profiles['google-plus'] = 'https://plus.google.com/+wpmagru';   return $profiles;  }  add_filter( 'my_social_profiles', 'change_my_social_profiles' );  

Фильтры и события в ядре WordPress

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

Отключить комментирование

Отключить комментирование на всем сайте, на зависимо от настроек в параметрах можно с помощью следующего кода:

function my_comments_open() { return false; }  add_filter( 'comments_open', 'my_comments_open' );  

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

Кстати, ядро WordPress определяет несколько вспомогательных функций для работы с подобными фильтрами:

  • __return_true() — возвращает true
  • __return_false() — возвращает false
  • __return_zero() — возвращает 0
  • __return_empty_string() — возвращает пустую строку
  • __return_empty_array() — возвращает пустой массив
  • __return_null() — возвращает null

То есть наш фильтр на comments_open можно переписать в одну строку:

add_filter( 'comments_open', '__return_false' );  

Изменить длину автоматических цитат

За длину автоматических цитат отвечает фильтр excerpt_length:

function my_excerpt_length( $length ) {   $length = 10;   return $length;  }  add_filter( 'excerpt_length', 'my_excerpt_length' );  

С помощью фильтра excerpt_more можно изменить текст, который который ставится в конце автоматический цитаты, по умолчанию это [...]:

function my_excerpt_more( $more ) {   $more = '&rarr;';   return $more  }  add_filter( 'excerpt_more', 'my_excerpt_more' );  

Добавить баннер к содержимому каждой статьи

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

function my_banner( $content ) {   $banner = '<a href="#"><img src="..." /></a>';   $content = $banner . $content;   return $content;  }  add_filter( 'the_content', 'my_banner' );  

Добавить favicon.ico в раздел <head>

В разделе <head> в каждой теме выполняется событие wp_head. Во время этого события можно вывести ссылку на файл favicon.ico, вставить произвольный код JavaScript или CSS и многое другое:

function my_favicon() {   echo '<link rel="shortcut icon" href="http://example.org/favicon.ico" />';  }  add_action( 'wp_head', 'my_favicon' );  

Учтите, что если вам необходимо подключить внешние .js или .css файлы, делать это стоит с помощью функций wp_enqueue_script() и wp_enqueue_style() во время события wp_enqueue_scripts, а не напрямую в wp_head.

В каждой версии WordPress добавляются все больше и больше новых и полезных фильтров и событий. Список большинства фильтров и событий в ядре можно посмотреть на сайте Адама Брауна, или просканировав файлы ядра на «do_action» и «apply_filters».

Приоритеты

Функции добавленные к фильтрам и событиям выполняются в том же порядке, в котором они были добавлены, но порядок легко изменить с помощью приоритетов. Приоритет указывается третьим аргументом к функциям add_action() и add_filter().

Без указания этого аргумента функции к фильтрам и событиям добавляются по умолчанию с приоритетом 10. Функции выполняются от меньшего приоритета к большему, т.е. чем меньше приоритет, тем раньше выполняется функция.

Вернемся к примеру с цифрами:

add_action( 'foo', 'one' );  add_action( 'foo', 'two' );  add_action( 'foo', 'three' );    do_action( 'foo' ); // выведет 123  

Если изменить приоритет выполнения функции three() на 9, то она выполнится раньше остальных:

add_action( 'foo', 'one' );  add_action( 'foo', 'two' );  add_action( 'foo', 'three', 9 );    do_action( 'foo' ); // выведет 312  

Подобным образом, указав приоритет 11 для функции one(), она выполнится позднее всех остальных, несмотря на то, что она была добавлена первой с помощью add_action():

add_action( 'foo', 'one', 11 );  add_action( 'foo', 'two' );  add_action( 'foo', 'three', 9 );    do_action( 'foo' ); // выведет 321  

Дополнительные параметры

В каждую функцию, привязанную к фильтру или событию, легко передать дополнительные параметры. Делается это при вызове функций do_action() или apply_filters(), например:

do_action( 'foo', $arg1, $arg2, $arg3 );  $value = apply_filters( 'foo', $value, $arg1, $arg2, $arg3 );  

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

Например, если в функции к событию foo мы хотим принять все три аргумента, необходимо указать 3 в качестве четвертого параметра к add_action():

function my_func( $arg1, $arg2, $arg3 ) { ... }  add_action( 'foo', 'my_func', 10, 3 );  

Подобным образом, если в функции добавленной к фильтру мы хотим принять только $arg1 в качестве дополнительного аргумента, то просим add_filter() передать всего два аргумента — первый аргумент $value, и второй дополнительный аргумент $arg1:

function my_func( $value, $arg1 ) { ... }  add_filter( 'foo', 'my_func', 10, 2 );  

Пример

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

add_filter( 'allow_password_reset', '__return_false' );  

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

function my_filter( $allow, $user_id ) {   if ( is_super_admin( $user_id ) )   $allow = false;     return $allow;  }  add_filter( 'allow_password_reset', 'my_filter', 10, 2 );  

Учтите, что функции привязанные к фильтрам могут изменять только первый аргумент, передаваемый в фильтр. То есть функция приведенная выше может изменить только аргумент $allow, но не $user_id.

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

ООП, классы, объекты и анонимные функции

Разработчики тем и плагинов WordPress часто предпочитают объектно-ориентированный стиль программирования, где большая часть кода выполняется внутри объекта, а не в глобальном пространстве. Если функциям add_action() и add_filter() необходимо передать не функцию для вызова, а метод объекта, его необходимо передать в специальном формате массивом:

class My_Class {   function __construct() {   add_filter( 'the_content', array( $this, 'filter_content' ) );   }     function filter_content( $content ) {   // ...   return $content;   }  }  new My_Class();  

Похожим образом можно передать статический метод класса:

add_filter( 'the_content', array( 'My_Class', 'filter_content' ) );  add_filter( 'the_content', 'My_Class::filter_content' ); // PHP >= 5.2.3  

Фильтры и события поддерживают и анонимные функции, например:

add_filter( 'the_content', create_function( '$content', 'return $content;' ) );  add_filter( 'the_content', function( $content ) { return $content; } ); // PHP >= 5.3  

Пользоваться анонимными функциями с фильтрами и событиями в WordPress мы не рекомендуем, поскольку их сложно отлаживать (например с помощью плагина Debug Bar Slow Actions) а функция create_function() не кэшируется на уровне байт-кода, например в APC.

Заключение

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

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

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

wpmag.ru

Yes, programmers must speak conceptually to communicate to a broader audience simply because of the self-taught, DIYer, people don’t really understand. Yes technically, do_action() calls another function _wp_call_all_hook() that uses the PHP function call_user_func_array() to call a variable function. However, it is still correct to say that do_action essentially creates the hook.

In my personal opinion, I believe in modular functional code based on a framework created by do_action(). You’re right in that the way my code was written in that post is not the best representation. And it is true that if you have do_action() followed by add_action() the add_action() will not be executed. Here’s what typically happens in WordPress. Take a home.php example. Here’s an example of a home.php using hooks.
[php]
<?php get_header();
do_action( ‘wps_home_before_banner’ ); ?>
<div id="banner">
<?php do_action( ‘wps_banner’ ); ?>
</div><!– end #banner –>
<div class="banner-shadow"></div>

<?php
do_action( ‘wps_home_before’ ); ?>
<div id="content-sidebar-wrap">
<div id="content">
<?php do_action( ‘wps_content’ ); ?>
</div>
<?php get_sidebar(); ?>
</div>

<?php do_action( ‘genesis_home_after’ );

get_footer();
[/php]

So in this code, I’ve hardcoded a frame with some hooks to write modular code. While I still do not believe this to be the best method, it is how more and more themes are operating. As you can see I have no add_action() statements here. In other files (e.g., functions.php, other theme files, a plugin, etc.) I would have the functions that hook into this to create the home page. So consider a home-functions.php that looks something like this:
[php]<?php
add_action( ‘wps_banner’, ‘wps_do_banner’ );
/**
* Outputs widgeted slider area
*/
function wps_do_banner() {
?>
<div class="slider">
<?php if ( ! dynamic_sidebar(‘home-slider’ ) ) : ?>
<div class="widget">
<h3><?php _e( ‘Home Slider’, ‘genesis’ ); ?></h3>
<p><?php _e( ‘Designed for a Slider’, ‘genesis’ ); ?></p>
</div>
<?php endif; ?>
</div><!– end .slider –>
<?php
}

add_action( ‘wps_banner’, ‘wps_do_search’ );
/**
* Outputs widgeted search area
*/
function wps_do_search() {
?>
<div class="home-search">
<h3><?php _e( ‘Homes for Sale’ , ‘genesis’ ); ?></h3>
<?php if ( !dynamic_sidebar( ‘home-search’ ) ) : ?>
<div class="widget">
<h3><?php _e(‘Home Search Area’ , ‘genesis’ ); ?></h3>
<p><?php _e(‘Designed for the MLS Home Search Widget’ , ‘genesis’ ); ?></p>
</div>
<?php endif; ?>
</div><!– end .home-search –>
<?php
}

add_action( ‘wps_banner’, ‘wps_clear’ );
/**
* Outputs clearfix
*/
function wps_clear() {
echo ‘<div class="clear"></div>’;
}

add_action( ‘wps_banner’, ‘wps_banner_bottom’ );
/**
* Outputs widgeted call of actions area
*/
function wps_banner_bottom() {
?>
<?php if ( is_active_sidebar( ‘banner-bottom’ ) ) : ?>
<div class="bottom-widget">
<div class="wrap">
<?php if ( ! dynamic_sidebar( ‘banner-bottom’ ) ) : ?>
<div class="widget">
<h3><?php _e(‘Widget Area’, ‘genesis’ ); ?></h3>
<p><?php _e(‘Designed for Call of Actions or Featured Listings’, ‘genesis’ ); ?></p>
</div>
<?php endif; ?>

</div><!– end .wrap –>
</div><!– end .bottom-widget –>

<?php
endif;
}

add_action( ‘wps_content’, ‘wps_do_feature_content’ );
/**
* Outputs widgeted feature content area
*/
function wps_do_feature_content() {
?>
<?php if ( ! dynamic_sidebar( ‘Home’ ) ) : ?>
<div class="widget">
<h3><?php _e( ‘Widget Area’ , ‘genesis’ ); ?></h3>
<p><?php _e( ‘Designed for Call of Actions or Featured Listings’, ‘genesis’ ); ?></p>
</div>
<?php endif; ?>
}
[/php]

Now in a framework like Genesis, this becomes much simpler because these hooks pre-exist inside the genesis() function call, so hardcoding a home.php file is not necessary. So the home.php file would look more like the second part of modular function code than anything. So…
[php]<?php

// Remove Breadcrumbs
remove_action(‘genesis_before_loop’, ‘genesis_do_breadcrumbs’);

// Add Banner
add_action( ‘genesis_after_header’, ‘wps_do_banner’ );
//previous code

// Add Search widget
add_action( ‘genesis_after_header’, ‘wps_do_search’ );
//previous code

add_action( ‘genesis_after_header’, ‘wps_clear’ );
//previous code

add_action( ‘genesis_after_header’, ‘wps_banner_bottom’ );
//previous code

// Add Optional Features Area
add_action( ‘genesis_before_loop’, ‘wps_do_feature_content’ );
//previous code

genesis();
[/php]

Even using genesis(); I am calling all the add_actions prior to the execution of the do_actions. Does this clarify a bit more?

wpsmith.net


You May Also Like

About the Author: admind

Добавить комментарий

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.