WordPress add action


While designing your themes, often times you want to be able to push dynamic content to a particular area of it.  The do_action(), add_action() functions of WP are a great tool to use.

These functions in wordpress allow you to specify a point in the code to trigger or initiate another segment of code.    Like an extension to the original code that’s placed there.   This is used so that different plugins that are created can use those ‘hooks’ in the wordpress code to add to the original core code without having to actually edit the core code itself.

do_action()
http://codex.wordpress.org/Function_Reference/do_action

The WordPress.ORG Codex refers to the usage as:

<br /> do_action($tag, $arg = );<br /> 

The $tag refers to the ‘Label’ you specify to hook into; with your add_action function.   The $arg = refers to the arguments that you want to pass through the do_action and into the add_action.


.. That really doesn’t say much on how to actually use the do_action.    What the do_action() function does is set’s a label in a specific point in your code for your plugin or theme code to hook into with the add_action() function.

For example, I place a do_action() right above the blog area of my theme.

<br /> do_action('mytheme_aboveblog');<br /> 

What you’re doing when you add the do_action is make it so that at that place in your code you can inject some other code into it. What makes this different then actually hardcoding the function name there? Using the do_action() allows multiple functions to access that particular point in the place you put it at, not just one, which you can use to set different events to occur to trigger them to display or be used there.

add_action()
http://codex.wordpress.org/Function_Reference/add_action

The WordPress.ORG Codex refers to the usage as:

<br /> add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1);<br /> 

The $tag refers to the label you specified as the hook in the do_action() function.   $function_to_add refers to what the name of the function is inside your plugin to execute, $priority refers to how much of a priority is given to execution of this function and $accepted_args refers to the number of arguments passed through do_action() to the $function_to_add.


What this is really saying?   The add_action finds the label specified in the $tag and hooks into it saying to that bit of code to “execute this function in addition to what you’re already doing, oh and pass these arguments.”  For example, in my activity monitor plugin:

<br /> add_action('mytheme_aboveblog',  'mytheme_online_user_message');<br /> 

Now, whenever the do_action checks for something to be injected into it to be used the add_action will trigger the function mytheme_online_user_message to run.

<br /> function mytheme_online_user_message() {<br /> 	global $current_user;<br /> 	if (!empty($current_user)) {<br /> 		$user_login = addslashes($current_user-&gt;user_login);<br /> 		echo &quot;Hello {$user_login}!&quot;;<br /> 	}<br /> }<br /> 

Now if the user is logged on it will run this function in that do_action place you put it and if the user is online inject that message into that place.

Summary

Placing a do_action()  into your code allows other functions to hook into it to extend the functionality of where that hook is placed, using add_action().


frumph.net

In the previous tutorial of this series we introduced WordPress hooks and saw the differences between WordPress Actions and WordPress Filters. It´s time now for some action!

This post is intended for making clear what WordPress actions are, how they work, how to use them and how they are hooked to the right place or event. So if you finish the reading of this tutorial without having all that perfectly clear, or if you end up still thinking that WordPress actions are hard to deal with, it will all be my only fault because my motivation to write this post is to get just the opposite effect.

The Action Hook itself: The do_action function

Remember what I said on my previous post about the Terminology Confusion when referring to action and filter hooks? Let´s make concepts clear from the starting point:

The real action hook is none other than the string included in the $tag variable of the do_action($tag) when this function is found at the right place, thus marking an event for which we want our code to fire a particular action (or even more than one).

A bit messy? Not at all, as you will soon realize. Let´s see in detail what all this means.

If you look at the different php template files included in your WP theme, you will find here and there various examples of WP actions hooks. They come in the form of a do_action


function.

By definition, the do_action($tag) function invokes all functions attached to the action hook $tag.

A common example

We will begin with a standard WordPress action hook: wp_footer.

A good practice for every theme developer is to place the following code in the footer of the theme:

<?php
do_action( ‘wp_footer’ );
?>

Or, as we will see in a moment, just this:

<?php
wp_footer();
?>

That way, when that part of the code is reached, WordPress will look for any functions registered for the wp_footer hook, and will then execute them in the order desired (more on this in a moment). Which means that, without ever touching the core WP code, we are free to construct functions that will be executed every time the WordPress code reaches the footer of our page (or at least we should be able to do so, as long as our theme is properly coded).

Well, I used the term “good practice” above, but including the wp_footer


hook should really be considered a must. It is good practice for theme developers to include hooks in as many places as possible, at least where somebody could think of including a custom function.

The wp_footer hook is very widely used for placing some particular pieces of code before closing the body of our page. For example it´s used by plugins to inject scripts in the site html footer, or it could also be used to place special tracking codes like the ones used by Google Analytics. And a perfect example of functionality hooked to wp_footer is the WordPress admin bar that you see in top of your page when you are logged in.

But let us see this hook in the real world.

Got a wrench at hand? Let´s take a look at the Twenty Fourteen theme. More precisely, let´s look at how the footer.php template file is coded:

Can you see the line <?php wp_footer(); ?> down there, right before the closing body tag?

It doesn´t look like a do_action function at first sight, but it actually is a very simple WP core function (included in the general-template.php file inside the /wp-includes/ folder of your WP installation), as simple as this:

function wp_footer() {
do_action('wp_footer');
}


Which means that the wp_footer function is an action hook.

How to “get hooked”: The add_action function

The way to hook our functions to the event marked by the hook we´re interested in is by means of the WordPress core function add_action. In its simplest form, it looks like this:

<?php add_action( $hook, $function_to_add ); ?>

According to the WordPress Codex,  it “Hooks a function on to a specific action. More specifically, this function will run the function $function_to_add when the event $hook occurs“.

It couldn´t be simpler, could it? Well, you might not see it that clear now until you see this stuff working. But don´t worry, you´ll do in just a moment.

Before that, let me just explain that when I wrote “its simplest form” it was because the add_action function can accept optional arguments, and it can also handle optional priorities. So, for your information, the complete form of this function would be like this:

<?php add_action( $hook, $function_to_add, $priority, $accepted_args ); ?>

That´s why I said before that WordPress will look for any functions registered for a particular hook and execute them in the desired order. Quoting the WordPress Codex again, the $priority


 parameter is “Used to specify the order in which the functions associated with a particular action are executed. Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action“. If no priority is specified, WordPress will assign the default value: 10.

Let´s play with action hooks

I know that by now you are tired of definitions and would like to get some action. Am I right?

But hey, wait a moment. I think WordPress actions are playing hide-and-seek with you!

Didn´t you see any other action hook in the footer.php template file from Twenty Fourteen theme above?

Yes, you got it right! There´s yet another one in this line:

<?php do_action( 'twentyfourteen_credits' ); ?>

Now that you´ve found it, we´re going to play with that action hook. You´ll notice that it is placed inside a div with a class named “site-info”, right before the line that generates the “Proudly powered by WordPress” message and link that appears at the footer of your site when you use Twenty Fourteen.


I´ll tell you what we´ll do: We are going to place our own credits before that message, and we´ll do it without touching the original footer.php template file, simply by hooking a custom function to that hook we´ve just discovered.

We will be using a custom function that I´ve already used in my post Add functions to your WordPress child theme (2) – Create a new function. Here it is:

We need to pass two arguments to this function (the name of the copyright claimer to be displayed and the starting year of the website), and then the function gets the current year, determines whether the current year is different from the starting one and constructs the text line that will constitute our copyright notice by including the copyright symbol (©), the year range (for example 2010 – 2013, or just 2013 if our site is new) and the claimer (for example your name).

If you have any doubts about this code, the way this function works is fully explained in the post I mentioned and linked above (I´m using here the function I called “Approach #1” on that post).

Once you add that function to the functions.php file of your child theme, you will only need to make it work whenever WordPress reaches the appropriate hook (twentyfourteen_credits in this case). You can do so for example by adding these lines of code to your functions.php file as well:

Let me explain what I did here:


  • First, I´ve created a new function my_custom_credits() that just echoes the text returned by the function my_updated_copyright($first_year, $owner) giving it a little styling: a 15px space to separate this text from the next (“Proudly powered by WordPress”).
  • I´ve provided the values I want to be displayed on the footer (in this example I´ve used 2010 for $first_year and “My Name” for $owner).
  • And, finally, I´ve hooked the new function my_custom_credits() to the twentyfourteen_credits action hook by using add_action( $hook, $function_to_add ); as we saw before.

Does it work? Sure it does, here is the resulting footer on my Twenty Fourteen test site:

wp-actions-footer

Of course, if you want to use this function hooking it to twentyfourteen_credits or to whatever other suitable hook in any other theme you may be using, remember to replace the values 2010 and My Name with the year you launched your site and your name or that of your business.


Conclusion

In this tutorial we have learned what WordPress actions are and how they work, and we have learned how to use them by means of an example.

By now all your fears about WordPress actions should be gone (or at least most of them). Otherwise, I would have failed like I said at the beginning of this post.

Let me know about your progress with actions hooks through the comments. And if you think that anything is not clear enough, let me know as well.

www.wpthemedetector.com

The Goal

The goal here is to describe and provide code that allows you to easily add your own custom bulk actions to any part of the WordPress admin: posts, media, users, whatever. The approach presented is based on this wordpress answers page. For this example, we’ll pretend we’re adding a custom action named “Export” to the posts page, to allow the bulk exporting of selected posts. Note that if you want to add custom bulk actions to one of the other sections, say the Users page, you’ll have to modify my code in a couple of places which I identify in the demo plugin comments. Our final result should look like this:

Wordpress add action

The Issue

That promising-looking filter bulk-actions-screenid currently only has the ability to remove bulk actions, not add them. This is clearly noted on the filters codex page, and in a code comment in the file wp-admin/includes/class-wp-list-table.php. As described in this trac ticket the issue isn’t so much how to add a new bulk action to the dropdown menu, as it is how to generically handle custom bulk actions. Since this is yet to be solved in the core, it requires a bit of hacking; however don’t worry no core files were harmed in the making of this plugin.

The Solution

Enough of the problems, on to the solution. Creating a custom bulk action breaks down to three components. First, adding an item to the bulk action select box:

 add_action('admin_footer-edit.php', 'custom_bulk_admin_footer');  function custom_bulk_admin_footer() {   global $post_type;   if($post_type == 'post') {  ?>  <script type="text/javascript">  jQuery(document).ready(function() {  jQuery('<option>').val('export').text('<?php _e('Export')?>').appendTo("select[name='action']");  jQuery('<option>').val('export').text('<?php _e('Export')?>').appendTo("select[name='action2']");  });  </script>  <?php  } } 

As you can see, here we use javascript to inject our new bulk action item into the two bulk action select dropdowns on the Posts edit page. This piece of code certainly isn’t poetry, but until a filter capable of adding items is added to the core, it will have to do.

The next step is the code that performs the bulk action. This is done with a hook on the load-* actions, as recommended in the Q&A page referenced above. Even with demo code, this function is fairly lengthy so I’ll leave most of it out, please reference my demo plugin for the full working implementation. Its main tasks are to:

  1. determine the action
  2. perform security checks
  3. perform the action
  4. redirect the client to a results page
 add_action('load-edit.php', 'custom_bulk_action');  function custom_bulk_action() {   // ...   // 1. get the action  $wp_list_table = _get_list_table('WP_Posts_List_Table');  $action = $wp_list_table->current_action();   // ...   // 2. security check  check_admin_referer('bulk-posts');   // ...   switch($action) {  // 3. Perform the action  case 'export':  // if we set up user permissions/capabilities, the code might look like:  //if ( !current_user_can($post_type_object->cap->export_post, $post_id) )  // pp_die( __('You are not allowed to export this post.') );   $exported = 0;   foreach( $post_ids as $post_id ) {  if ( !$this->perform_export($post_id) )  wp_die( __('Error exporting post.') );  $exported++;  }   // build the redirect url  $sendback = add_query_arg( array('exported' => $exported, 'ids' => join(',', $post_ids) ), $sendback );   break;  default: return;  }   // ...   // 4. Redirect client  wp_redirect($sendback);   exit(); } 

The third step is to display a notice describing the result of the action by hooking into admin_notices and rendering a message if we have the ‘exported’ request parameter that was set in the previous block of code:

 add_action('admin_notices', 'custom_bulk_admin_notices');  function custom_bulk_admin_notices() {   global $post_type, $pagenow;   if($pagenow == 'edit.php' && $post_type == 'post' &&  isset($_REQUEST['exported']) && (int) $_REQUEST['exported']) {  $message = sprintf( _n( 'Post exported.', '%s posts exported.', $_REQUEST['exported'] ), number_format_i18n( $_REQUEST['exported'] ) );  echo "<div class="updated"><p>{$message}</p></div>";  } } 

Which in action looks like:

Wordpress add action

Demo Plugin

And there you have it. Feel free to download and use as a starting point my demo plugin which has code similar to the above, but fully implemented and commented. Install like any other plugin, by uploading through the Admin, or by unzipping the plugin folder and placing in wp-content/plugins/. Activate the plugin, then go to Posts > All Posts and try out the ‘Export’ bulk action.

Download Custom Bulk Action Demo Plugin

If you have any issues, or suggestions to improve the code, please leave a comment below.

www.skyverge.com

Что такое хуки?

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

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

Вот его определение в Wikipedia:

Архитектура, управляемая событиями (англ. event-driven architecture, EDA) является шаблоном архитектуры программного обеспечения, позволяющим создание, определение, потребление и реакцию на события.

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

  • Программное обеспечение в определенные моменты может присылать вам сообщение о каком-то событии.
  • Мы, как разработчики, способны написать код, который отслеживает эти сообщения, а потом отвечает на них пользовательским кодом.

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

Использование JavaScript

Представьте, что вы работаете в сфере фронтенд разработки. У вас есть кнопка с ID атрибутом command-button, и когда пользователь нажимает на неё, то должно открыться диалоговое окно.

С помощью jQuery вы можете реализовать этот функционал вот так:

(function( $ ) {   'use strict';      // jQuery's DOM-ready event-handler   $(function() {      /**   * Listen for the 'click' event on the button identified   * with the 'command-button' ID attribute.   *    * When the user clicks on it, display an alert dialog.   */   $( '#command-button' ).bind( 'click', function( evt ) {   alert( 'You clicked the button.' );   });      });     })( jQuery );

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

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

Использование WordPress

Применение этого шаблона разнится в зависимости от языка программирования или парадигмы. Это часто зависит от API, который предоставляет платформа или приложение.

В WordPress регистрация собственного кода, запускающего события, немного отличается. К примеру, давайте представим, что вы работаете с административной страницей в WordPress и хотите добавить новый элемент подменю в меню Настройки. Назовём его Tuts+ Options.

Для этого мы добавляем следующий код в файл functions.php, или в плагин, или в любой тип проекта, с которым мы работаем:

<?php     add_action( 'admin_menu', 'tutsplus_admin_menu' );  /**   * Adds a 'Tuts+ Options' submenu to the 'Settings'   * menu in the WordPress administration menu.   */  function tutsplus_admin_menu() {      add_submenu_page(   'options-general.php',   'tutsplus-admin-menu',   'Tuts+ Options',   'manage_options',   'tutsplus-admin-menu-top',   'tutsplus_admin_options'   );  }

Вы можете зайти на Codex, чтобы больше узнать о хуках admin_menu и функции add_submenu_page.

Этот код не добавляет никаких новых функций в меню, но он показывает, что WordPress предоставляет событие admin_menu так же, как браузер предоставляет события по клику. Мы тогда сможем ввести наш собственный код, определив функцию, и запуская её при возникновении события.

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

Понимание WordPress Actions

Мы успели ознакомиться с событийно-управляемым шаблоном разработки и двумя видами реализации шаблонов, а теперь давайте рассмотрим хуки действий WordPress. Мы расскажем о доступных хуках и их применении.

Настройка нашего файла

Для кода в этом руководстве мы будем использовать тему Twenty Sixteen, предоставляемую WordPress.

Создайте файл с названием tutsplus-actions.php в корне директории темы. Потом в functions.php добавьте следующие строки кода:

<?php  include_once( 'tutsplus-actions.php' );

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

Краткое определение Actions

В WordPress хуки могут быть двух видов: хуки действий (actions) и хуки фильтров (filters). Хуки действий позволяют вам добавлять, удалять или менять определённые функции. А хуки фильтров отвечают за добавление, удаление и изменение информации.

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

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

Хотя технически всё правильно, но лучше определить тип хука, над которым вы работаете.

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

Работа с Actions

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

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

А одной из особенностей, которая делает WordPress расширяемым, является возможность представлять собственные типы записей (custom post types). WordPress называет их пользовательскими типами записей, и они пригодятся, если вам нужно создать тип контента, которому нужен собственный тип атрибутов, и которому не подходят названия «запись» или «страница».

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

  1. Определить функцию, которая цепляется за хук init, как указано на WordPress
  2. Зарегистрировать наш тип записи с помощью одной из доступных функций API

Регистрация Action

Чтобы зарегистрировать наш хук действия, мы используем функцию add_action, предоставляемую WordPress API. Это сообщит WordPress, что мы представляем хук действия и что нужно запустить функцию, определённую названием, которое мы указали в вызове функции.

Наш код должен выглядеть так:

<?php  add_action( 'init', 'tutsplus_register_post_type' );

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

Теперь нужно определить функцию.

<?php  function tutsplus_register_post_type() {     }

Ключ к пониманию названия функции прост: Мы назвали ее tutsplus_register_post_type, поскольку это второй аргумент, который мы переместили в вызов add_action.

Он буквально говорит WordPress делать следующее: во время init вызвать функцию tutsplus_register_post_type.

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

Давайте это исправим.

Создание пользовательского типа записи

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

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

Мы выбрали следующие:

  • label
  • labels
  • description
  • public
  • show_ui
  • supports

Мы надеемся, что остальные функции WordPress предоставляет автоматически. Аргументы будут выглядеть так:

<?php $args = array( 'label' => 'Time Travelers',   'labels' => array(   'name' => 'Time Travelers',   'singular_name' => 'Time Traveler',   'add_new_item' => 'Add New Traveler',   'edit_item' => 'Edit Traveler',   'new_item' => 'New Traveler',   'view_item' => 'View Traveler',   'search_items' => 'Search Travelers',   'not_found' => 'No Travelers',   ),   'description' => 'A post type used to provide information on Time Travelers.',   'public' => true,   'show_ui' => true,   'supports' => array(   'title',   'editor',   'excerpt',   ),  );

И наконец, полная версия кода для регистрации типа записи:

<?php add_action( 'init', 'tutsplus_register_post_type' ); function tutsplus_register_post_type() { $args = array( 'label' => 'Time Travelers',   'labels' => array(   'name' => 'Time Travelers',   'singular_name' => 'Time Traveler',   'add_new_item' => 'Add New Traveler',   'edit_item' => 'Edit Traveler',   'new_item' => 'New Traveler',   'view_item' => 'View Traveler',   'search_items' => 'Search Travelers',   'not_found' => 'No Travelers',   ),   'description' => 'A post type used to provide information on Time Travelers.',   'public' => true,   'show_ui' => true,   'supports' => array(   'title',   'editor',   'excerpt',   ),   );      register_post_type( 'time_traveler', $args );     }

После обновления Консоли должен появиться новый пункт прямо под Комментариями с названием Time Travelers.

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

Добавление кастомных хуков в WordPress: Custom Actions» />

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

Определение Custom Actions

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

  1. определить хук
  2. наделить хук функцией
  3. разрешить разработчикам вызывать хук

Самый простой пример:

<?php     /**   * Define the action and give functionality to the action.   */   function tutsplus_action() {   do_action( 'tutsplus_action' );   }      /**   * Register the action with WordPress.   */  add_action( 'tutsplus_action', 'tutsplus_action_example' );  function tutsplus_action_example() {   echo 'This is a custom action hook.';  }

Не бойтесь добавлять этот код в tutsplus-actions.php, вы сможете изучить его подробнее после прочтения нашей статьи.

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

<?php     add_action( 'admin_notices', 'tutsplus_admin_notice' );  function tutsplus_admin_notice() {   tutsplus_action();  }

После обновления консоли, вы увидите надпись «This is a custom action hook» вверху консоли.

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

К вопросу о нашем типе записи

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

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

<?php     function tutsplus_register_custom_post_type() {      // Set the action at priority of 10 and note that it accepts 2 arguments.   do_action( 'tutsplus_register_custom_post_type', 10, 2 );     }

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

Для этого мы присоединяем наш пользовательский хук к хуку инициализации:

<?php  add_action( 'init', 'tutsplus_register_custom_post_type' );  function tutsplus_register_custom_post_type() {      // Set the action at priority of 10 and note that it accepts 2 arguments.   do_action( 'tutsplus_register_custom_post_type', 10, 2 );     }

Обратите внимание, что в вышеизложенном коде мы указали два дополнительных параметра для do_action. Первым параметром является 10, который показывает приоритет запуска хука.

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

После этого нам нужно наделить хук функционалом. Мы выполним перепроектирование кода для регистрации типа записи, чтобы он принял два аргумента, которые будут использованы в массиве, переданном WordPress функции register_post_type.

<?php function tutsplus_register_post_type( $singular, $plural ) { $args = array( 'label' => $plural,   'labels' => array(   'name' => $plural,   'singular_name' => $singular,   'add_new_item' => 'Add New Traveler',   'edit_item' => 'Edit Traveler',   'new_item' => 'New Traveler',   'view_item' => 'View Traveler',   'search_items' => 'Search Travelers',   'not_found' => 'No Travelers',   ),   'description' => 'A post type used to provide information on Time Travelers.',   'public' => true,   'show_ui' => true,   'supports' => array(   'title',   'editor',   'excerpt',   ),   );      register_post_type( 'time_traveler', $args );     }

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

<?php  add_action( 'tutsplus_register_custom_post_type', 'tutsplus_register_time_traveler_type' );  function tutsplus_register_time_traveler_type() {   tutsplus_register_post_type( 'Time Traveler', 'Time Travelers' );  }

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

Итоги

Не тяжело понять, что такое хуки. Они добавляют разработчикам мощности и гибкости. Возможно, наиболее пугающей вещью в коде является определение хука в контексте другого хука (определение tutsplus_register_custom_post_type в init).

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

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

hostenko.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

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

Я не создаю плагин, так как я не знаком с ним.

  • Как включить тип сообщения в админ / бэкэнд?
  • Каков наилучший способ «включить» файл в WordPress?
  • PHP help get_template_directory + PHP include
  • Как я / возможно ли выполнить внешний PHP-файл / функцию внутри WordPress?
  • Файлы PHP, включенные в функции functions.php, не работают из области администрирования
  • Добавьте несколько идентификаторов сообщений в wp_query

Я написал следующий класс, но я не смог полностью его обработать. Как только функция _setup вызывается, в исходном коде выводится что-то еще. Аналогично, все add_action ('wp_head') игнорируются.

Я подозреваю, что это потому, что я вспоминаю класс слишком поздно, но я не знаю, так ли это, и как я могу его проверить.

class Stuff_Frontend { private static $_instance = null; public static function init() { add_action( 'wp_head', array(self::instance(), '_setup')); } public static function instance() { // create a new object if it doesn't exist. is_null(self::$_instance) && self::$_instance = new self; return self::$_instance; } /** * Setup the class * Adds and removes a lot of filters. */ function _setup() { echo "I'm here;"; add_action( 'wp_head', array(self::instance(), 'head' ), 1 ); // Remove actions that we will handle through our wpseo_head call, and probably change the output of remove_action( 'wp_head', 'rel_canonical' ); remove_action( 'wp_head', 'index_rel_link' ); remove_action( 'wp_head', 'start_post_rel_link' ); remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head' ); remove_action( 'wp_head', 'rsd_link' ); remove_action( 'wp_head', 'wlwmanifest_link' ); add_action( 'mystuff', array(self::instance(), 'change_metadesc' ), 10 ); } /** * Main wrapper function attached to wp_head. This combines all the output on the frontend. */ public function head() { echo "this is a test for my class head"; /** * Action: 'mystuff' */ do_action( 'mystuff' ); return; } /** * Change the meta description element. * * @param bool $echo Whether or not to echo the description. * * @return string */ public function change_metadesc() { echo "this is an attempt to change the description"; } } 

Класс, описанный выше, вызывается в функции.php ini, используя следующие утверждения:

 include( locate_template( 'MyStuff.php' ) ); Stuff_Frontend::init(); 

Любые намеки приветствуются. благодаря

Solutions Collecting From Web of «add_action вне плагина»

www.wordpressask.com


You May Also Like

About the Author: admind

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

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

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