Apply filters


Большинство из следующих могут быть найдены в Codex:


apply_filters

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

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

В сущности:
используется apply_filters для фильтр данный $ value — относительно самого значения, а также при необходимости предусмотренных переменных $var_1 через $ var_n.


add_filter

Hook функцию для конкретного действия фильтра.

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

В сущности:
Вы используете 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  

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

Второй раз, мы получаем инициалы в обратном порядке —, так как функция фильтра __return_true


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

wordpress.stackovernet.com

Что такое 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

Extensions: Plugins for Plugins

So it’s clear what we’re talking about when we say “extensions,” let’s take an example: Stripe for WooCommerce.

This extension does nothing if you don’t already have WooCommerce. If you do, though, you purchase and install Stripe for WooCommerce as a separate plugin, and it broadens WooCommerce’s functionality so that you can start accepting payments through the Stripe payment gateway.

So you’ve got a plugin improving another plugin in a specific way. That’s an extension. They’re the adverbs of the WordPress tech ecosystem.

How Extensions Work: apply_filters() and do_action()

Extensible WordPress plugins make liberal use of two functions: apply_filters() and do_action()


, the two ways of creating WordPress hooks.

The next question: how did WooCommerce do that? After all, it’s easy to imagine writing an e-commerce plugin that “only works with the gateways it works with.” Then if you really want Stripe you have to tear apart WooCommerce, and probably end up creating your own proprietary thing called StripeCommerce, which either becomes a competitor to WooCommerce or just lives on the site of the one client who could afford to pay you for the development and ongoing bugfixes.

It’s a mess to contemplate, but fortunately WooCommerce does something much better. It makes liberal use of two functions: apply_filters() and do_action(). These two functions are the two ways of creating hooks in WordPress, and a foundational part of WordPress’s Hooks system in general.

apply_filters() and do_action() have one simple difference:

  1. apply_filters() is how you hook in filter functions.
  2. do_action() is how you hook in action functions.

Let’s look at a live example to see how they work.

A Working Example: A Plugin and Its Extension

For our example, we’ll use a working “Quote of the Day” plugin, plus an extension that modifies that plugin in specific ways. To follow along and see the full code, download both plugins as a ZIP file.


The Original Plugin: Quote of the Day

This plugin pulls from the API exposed by an external library of quotes, storing the resulting quote as a WordPress transient that refreshes once every 24 hours. Come back to this article anytime and you’ll see that day’s random quote on the topic of “life”—which should be suitably broad.

The default plugin displays itself using a shortcode, and looks as follows:

One’s real life is so often the life that one does not lead.

Oscar Wilde

The Extension: Carl Sagan Quote of the Day

As we know, the problem with most quotes is that they weren’t said by Carl Sagan, the astronomer who made a career out of blowing the collective mind of late-20th-century Earth. Our extension fixes that problem, using a number of tools:

  1. A large header indicating today’s date and that the quote is by Carl Sagan,
  2. Some specific word replacements to make any quote into something Carl Sagan would say,
  3. Original quote authors are crossed out and quotes are now correctly attributed to Carl Sagan, and
  4. Below every quote is a graphic of a Carl Sagan impersonator utterly annihilating your most fundamental grasp on reality, as a multimedia reminder of what Carl Sagan quotes are like.

Here’s the plugin, plus extension, in action:

Carl Sagan Quote of the Day for November 13, 2018:

One’s real life seems, without the mind-boggling perspective of quantum physics, to be so often the trillions of atoms that make up the life that one does not lead.

Oscar Wilde Carl Sagan

The Code

The code to make this happen works in two steps:


  1. The original plugin defines hooks—both action hooks and filter hooks—allowing outside code to modify or add to its own code at key points. The plugin uses apply_filters() and do_action() to accomplish this.
  2. The extension defines hooked functions—both actions and filters—that modify the original plugin in the needed ways.

Key Code in the Original Plugin

We’re not going to cover how we make our API call to the quote database, but that’s quite interesting and is a textbook use of wp_remote_get(), so again, please feel free to download the ZIP file containing both plugins.

The important code for us is what we do once we’ve gotten our API data. It comes in as an array with two elements: text, the quote text; and author, the person who said the quote. Our code looks as follows:

add_shortcode( 'extensible_plugin_demo', 'wpshout_output_extensible_plugin' ); fu.  

cho '<br><br>'; echo $qod_author; echo '<small></blockquote>'; } // Action hook after rest of output! do_action( 'wpshout_after_get_qod_text' ); return ob_get_clean(); }

The pieces to emphasize here (besides how handy output buffering comes in for shortcodes) are the following four lines:

  1. do_action( 'wpshout_before_get_qod_text' ); This will run any functions that have been hooked (using add_action()) to the action hook that we’re naming wpshout_before_get_qod_text. This all happens before the rest of the plugin’s code gets printed out. This action hook is what the extension is using to print “Carl Sagan Quote of the Day for [date]:” above the quote itself.
  2. $qod_text = apply_filters( 'wpshout_qod_text', $qod_text ); This will run any functions that have been hooked (using add_filter()) to the filter hook that we’re naming wpshout_qod_text. These are filter functions, meaning that they modify the output they’re given—$qod_text, which is the text content of the quote—and then give it back for further processing. This filter hook is what the extension uses to convert particular words from the quote into Carl Saganspeak.
  3. $qod_author = apply_filters( 'wpshout_qod_author', $qod_author ); This will run any functions that have been hooked (using add_filter()) to the filter hook that we’re naming wpshout_qod_author. This filter hook is what the extension uses to cross out the original quote author and place “Carl Sagan” after it.
  4. do_action( 'wpshout_after_get_qod_text' ); This will run any functions that have been hooked (using add_action()) to the action hook that we’re naming wpshout_after_get_qod_text. This all happens after the rest of the plugin’s code gets printed out. This action hook is what the extension uses to display the “Mind Blown” graphic below the quote.

To sum up: the plugin could just output its own information, but it goes out of its way—using apply_filters() and do_action() to create hooks at key places in the code. Its action hooks let other programmers add in or modify whatever they want, and its filter hooks let other programmers modify specific pieces of key content.

Key Code in the Extension

The extension is made up of nothing but actions and filters—modifications to the original plugin that take advantage of the plugin making space for those modifications. Here’s the code for the extension:

add_filter( 'wpshout_qod_text', 'wpshout_filter_qod_text' ); // Filter: Replace specific words in quote text with Carl Saganspeak function wpshout_filter_qod_text( $text ) { 	$text = str_replace(  		array( ' I ', ' me ', ' the ', ' is ', ' am ', ' are ' ), 		array( ' I, a descendent of savannah-dwelling hominids that somehow evolved an astounding capacity for self-reflection, ', ' the cooled-off stellar matter I call "me" ', ' the trillions of atoms that make up the ', ' seems, without the mind-boggling perspective of quantum physics, to be ', ' cannot, due to the Heisenberg Uncertainty Principle, be determined not to be ', ' appear to our best scientific instruments to be ' ), 		$text 	); 	return $text; }  // Filter: Strikethrough old author and add "Carl Sagan" after add_filter( 'wpshout_qod_author', 'wpshout_filter_qod_author' ); function wpshout_filter_qod_author( $text ) { 	$text = '<strike>' . $text . '</strike> Carl Sagan'; 	return $text; }  // Action: Add title before quote add_action( 'wpshout_before_get_qod_text', 'wpshout_set_up_quote' ); function wpshout_set_up_quote() { 	echo '<h4>Carl Sagan Quote of the Day for ' . date( 'F j, Y') . ':</h4>'; }  // Action: add "mind blown" image add_action( 'wpshout_after_get_qod_text', 'wpshout_add_carl_boom' ); function wpshout_add_carl_boom() {  	echo '<div><img class="aligncenter" src="' . plugin_dir_url( __FILE__ ) . 'carl_sagan_mind_blown.gif"></div>'; }

As you can see, these are quite standard uses of add_action() and add_filter()—and both functions are hooking into the hooks we named (for example, wpshout_qod_text), just like they would any other hook.

The end result is that our plugin is extensible: a second developer can look at the daily quote plugin, say “I want to Carl Sagan-ize that,” and do it while still using the original plugin as a base—quite a bit like how parent and child themes work on the presentation side.

This trick, times about 1000, is what makes a giant plugin like WooCommerce able to have a rich extensions ecosystem—and integrate with MailChimp, Salesforce, Authorize.net, and your tax preparation software, all while hitting its core job of “listing products online” out of the park.

wpshout.com

THE SCENARIO:

NOTE: This can be modified to suit any need

On a single post, a user wants/requires to show custom content dynamically after the post to suit his needs. This should be dynamic. The content should be a custom query, and the user needs to choose what to show whenever he wants and what he wants

THE POSSIBLE SOLUTION:

Shortcodes will not work here, as shortcodes can’t be executed in custom fields. Neither will do_shortcode work, as it is not dynamic and is hardcoded, something we don’t want. As in your question, we are going to make use of a custom fields. Again I stress, do not use the custom field to execute a custom query or shortcodes

THE PLAN:

We will use the custom field to only save our query arguments, that is all. So, what we do is, we create a custom field called custom_query_arguments. In your post editor screen, you will now see your custom field, ready for use

The next step will be to add our custom query arguments to our field. Lets say, we need to show 3 posts from category 1 sorted by title. So our query arguments should look like this: (In string format)

'posts_per_page=3&cat=1&orderby=title' 

This is what you should now enter in your custom field. Once entered, save the value of your custom field

Next will be to construct the custom query in your single.php. What is needed here, we need to get the value from our custom field, which is actually our query arguments, and feed that to a new instance of WP_Query to retrieve the posts. We also need to check whether or not we actually have a value saved in that custom field, if the custom field is empty, show nothing

THE CODE:

You can try something like this in single.php just after the single post.

$args = get_post_meta( get_queried_object_id(), 'custom_query_arguments', true ); // check if the custom field has a value if( ! empty( $args ) ) {   $q = new WP_Query( $args );   if( $q->have_posts() ) {  while( $q->have_posts() ) {  $q->the_post();   the_title();   }  wp_reset_postdata();  }  }  

If the user wants to remove the custom query, he can simply just delete the value of the custom field and leave the custom field blank. If he needs to show the same query but from category 10 and a total of 5 posts, he can just replace the original value with the following

'posts_per_page=5&cat=10&orderby=title' 

FEW NOTES:

It is important to use the correct synatx and format when entering info into this custom fields and meta boxes. Syntax errors or incorrect info will lead to undesired output or even fatal errors. It is important to let your clients know of such info

ORIGINAL ANSWER

I don’t understand what you are trying to accomplish, but from what I can tell you, those are two separate things

OPTION 1

apply_filters('the_content', $content); is used to apply the content filters to raw unfiltered post content, which usually comes from the use of $post->post_content. These filters include the famous filter wp_autop which adds p tags to the_content()

apply_filters('the_content', $content); is usally used in conjuction with get_posts where one works directly with the WP_Post objects without using setup_postdata( $post ) which makes the template tags like the_content() available for use

OPTION 2

do_shortcode is used to add a shortcode anywhere in template files outside the text editor in the page editor screen back end, basically filtering shortcodes through their hooks.

The correct use is as follows

Example: Adding the gallery shortcode in a template file

echo do_shortcode( '' ) 

EDIT 1

From your comments, I would not use a shortcode at all then.

If you are not going to add a shortcode via the text editor and going to add it directly (hardcode) via do_shortcode in a template file, I would rather then just add the function to the template

Example:

If you have the following shortcode function

function footag_func( $atts ) {  return "foo = {$atts['foo']}"; } add_shortcode( 'footag', 'footag_func' ); 

You can simply call the function directly in a template like

echo footag_func(); 

It is much faster this way as the shortcode need not be parsed

EDIT 2

To be honest here, you are completely doing this wrong from your edit. That is why I could not understand your initial question

Sometimes, I need to add post meta on post/pages/custom post types, so that they can add shortcodes (slider, contact form etc) or just a simple text. It’s a text filed.

To make the shortcode working, I use option 1…..

Custom fields are not text fields and are surely not meant to be used to execute shortcodes and for that matter sliders or contact forms. Custom fields should never be used to replace the text editor in posts and pages.

As I stated before, apply_filters('the_content', $content); is meant to be used to apply formatting to raw post content.

You have two choices here

  • Use do_shortcode directly in template files, which I would not recommend as using the function is faster as the shortcode need not be parsed

  • Use the shortcode directly in the text editor for the particular page/post

I would seriously recommend that you take a fresh new look at your structures and what you want to achieve. Custom fields are not text editors and cannot execute shortcodes or sliders.

My recommendation would be to look maybe into custom widgets or a system which you can use with custom fields

wordpress.stackexchange.com

REST

 {  "filters": {  "dateFilter": {  "dates": [  {  "year": 2013  },  {  "year": 2011,  "month": 11  }  ],  "ranges": [  {  "startDate": {  "month": 1  },  "endDate": {  "month": 3  }  },  {  "startDate": {  "month": 3,  "day": 24  },  "endDate": {  "month": 5,  "day": 2  }  }  ]  }  } } 

Java

 // Create a new com.google.type.Date object for the year 2013 Date day2013 = Date.newBuilder()  .setYear(2013)  .build(); // Create a new com.google.type.Date object for November 2011 Date day2011November = Date.newBuilder()  .setMonth(11)  .setYear(2011)  .build(); // Create a date range for January to March DateRange dateRangeJanuaryToMarch = DateRange.newBuilder()  .setStartDate(Date.newBuilder().setMonth(1).build())  .setEndDate(Date.newBuilder().setMonth(3).build())  .build(); // Create a date range for March 24 to May 2 DateRange dateRangeMarch24toMay2 = DateRange.newBuilder()  .setStartDate(Date.newBuilder().setMonth(3).setDay(24).build())  .setEndDate(Date.newBuilder().setMonth(5).setDay(2).build())  .build(); // Create a new dateFilter with the dates and date ranges DateFilter dateFilter = DateFilter.newBuilder()  .addDates(day2013)  .addDates(day2011November)  .addRanges(dateRangeJanuaryToMarch)  .addRanges(dateRangeMarch24toMay2)  .build(); // Create a new Filters object Filters filters = Filters.newBuilder()  .setDateFilter(dateFilter)  .build(); // Specify the Filter object in the searchMediaItems call SearchMediaItemsPagedResponse response = photosLibraryClient.searchMediaItems(filters); 

PHP

 // Create a new GoogleTypeDate object for the year 2013 $date2013 = new Date(); $date2013->setYear(2013);  // Create a new GoogleTypeDate object for November 2011 $dateNovember2011 = new Date(); $dateNovember2011->setMonth(11); $dateNovember2011->setYear(2011);  $filtersBuilder = new FiltersBuilder();  // Create a date range for January to March $filtersBuilder->addDateRange((new Date())->setMonth(1),  (new Date())->setMonth(3));  // Create a date range for March 24 to May 2 $filtersBuilder->addDateRange((new Date())->setMonth(3)->setDay(24),  (new Date())->setMonth(5)->setDay(2));  $filtersBuilder->addDate($date2013); $filtersBuilder->addDate($dateNovember2011);  // Make a search call with the options set in the filters builder $response = $photosLibraryClient->searchMediaItems(  ['filters' => $filtersBuilder->build()] ); 

developers.google.com

Apply filters to all worksheets that use a related primary data source

This option applies the filter to all worksheets that use related data sources as their primary data source.

Note: To apply a filter to worksheets that use a related primary data source in web authoring, relationships between the data sources must be set up in Tableau Desktop, and then published to the web.

For more information, see Filter Data Across Multiple Data Sources.

To apply a filter to all worksheets using a related primary data source:

  • On the Filters shelf, right-click the field and select Apply to Worksheets > All Using Related Data Sources.

Filters that use this option are global across the workbook.

Filters that apply to all related data sources are marked with an icon. The filter is automatically created on any existing worksheets, and on any new worksheets you create that use a related data source.

Any changes you make to the filter affects all of those worksheets.

Apply filters to all worksheets that use the current primary data source

This option applies the filter to all worksheets that use the current worksheet’s primary data source as their primary data source.

To apply a filter to all worksheets using the current primary data source:

  • On the Filters shelf, right-click the field and select Apply to Worksheets > All Using This Data Source.

Filters that use this option are global across the workbook.

Filters that apply to all worksheets are marked with a data source icon Apply filters. The filter is automatically created on any new worksheets you create after you drag a field to the view.

Any changes you make to the filter affects all of those worksheets.

Note: If blending multiple data sources in a view, the All Using This Data Source option applies to the filter if it is the primary data source.

Apply filters to select worksheets (Tableau Desktop only)

This option opens a dialog box where you can select from a list of worksheets that use the same data source or related data sources.

To apply a filter to select worksheets:

  • On the Filters shelf, right-click the field and select Apply to Worksheets > Selected Worksheets.

  • In the Apply Filter to Worksheets dialog box, select the worksheets that you want to apply the filter. If any of the sheets already contain a filter on the same field, the dialog box will provide details about the filter.

    If you select the sheet, the current filter will override any existing filter selections.

    Apply filters

Filters that apply to a selection of worksheets are marked with the worksheet icon Apply filters. Any changes you make to the filter affect all of the selected worksheets.

Apply filters to the current worksheet only

This option only applies to the current worksheet. This option is selected by default when you create new filters. Filters that are local to the current worksheet are shown without any additional icons.

To apply a filter to the current worksheet only:

  • On the Filters shelf, right-click the field and select Apply to Worksheets > Only This Worksheet.

If you apply a filter to all worksheets or selected worksheets and then change the setting to apply the filter to just the current worksheet, the filters are not removed from all other worksheets. Rather, the filters are disconnected and they are all made local to their respective worksheets. You can go to each worksheet and remove the filter or modify selections.

Filter all worksheets on a dashboard (Tableau Desktop only)

This option applies the filter to all worksheets in the dashboard that use the same data source or related data sources as their primary data source.

To filter all worksheets on a dashboard:

  • In a dashboard, click the drop-down menu on a filter card and select Apply to Worksheets > Selected worksheets.

  • In the Apply Filter to Worksheets dialog box, click All on dashboard, and then click OK.

Note: In previous versions of Tableau Desktop, the All Using This Data Source option was called Make Global and the Only This Worksheet option was Make Local.

onlinehelp.tableau.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

Пример использования функции при фильтрации контента поста

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

Так вот, при помощи функции apply_filters() мы можем сами вручную отфильтровать контент из функции get_the_content().

Пошаговый пример создания своего собственного фильтра

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

У меня для простоты примера пусть это будет числовая переменная.

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

Теперь объединяем эти два листинга и вешаем фильтр.

А теперь сама фильтрующая функция, которую мы подвесим при помощи add_filter().

Как результат, получаем изменённое значение переменной. Если у вас есть трудности или вопросы по работе apply_filters(), оставляйте комментарий, обязательно помогу вам разобраться.

misha.blog


You May Also Like

About the Author: admind

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

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

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