WordPress как на ладони
Плагин рекламы для WordPress wordpress jino

Как работают хуки в WordPress (фильтры и события)

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

Хуками в WordPress называются фильтры (filter) и события (action). В программной части это абсолютно одно и тоже, т.е. обрабатывается и то и другое одинаково, можно например заменять функции add_filter() и add_action() — все будет работать! Разделение нужно, потому что по смыслу это разные вещи...

Фильтры нужны, чтобы отфильтровать передаваемое значение, т.е. фильтр получает значение и обязательно должен его вернуть (изменённое или нет). А события — это события, они просто срабатывают в определенный момент и ничего не возвращают.

Хуки нужны для того, чтобы к ним прикреплять PHP функции. Затем эти функции будут срабатывать в момент срабатывания хука.

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

Простой пример хука:

// создадим функцию для хука - события
function echo_1(){ echo 1; }

// привяжем функцию к хуку
add_action( 'my_hook', 'echo_1' );

// выполним хук
do_action('my_hook'); //> выведет 1

С передачей параметра:

// создадим функции для событий
function echo_1($data){ echo $data[0]; }
function echo_2($data){ echo $data[1]; }

// привяжем функции к хуку
add_action( 'my_hook', 'echo_1' );
add_action( 'my_hook', 'echo_2' );

// выполним хук
do_action('my_hook', array('Привет', ' мир!') ); //> выведет "Привет мир!"

Список фильтров смотрите на странице «Все хуки WordPress». Всего в WordPress их около 2000. Некоторые важные хуки я описал и продолжаю описывать они находятся тут.

Как работают фильтры в WordPress

Для работы фильтра используются две функции:

  1. apply_filters() — вызывается там, где применяется фильтр. Запускает добавленные к фильтру PHP функции.

  2. add_filter() — добавляет/прикрепляет PHP функции к указанному фильтру.

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

Пример

// Прикрепим функцию к фильтру.
// Это обычно делается в другом файле, но обязательно до вызова фильтра...
add_filter('my_filter', 'my_filter_function');
function my_filter_function( $str ){
	$str = 'Здравствуйте '. $str;
	return $str;
}

// Вызов фильтра
$str = 'Владимир';
$str = apply_filters('my_filter', $str );
echo $str; //> Здравствуйте Владимир

Еще пример

Допустим, у нас есть функция text(), которая возвращает текст. Нам нужно сделать так, чтобы можно было изменять этот текст за пределами этой функции. Для этого придумаем название нашему фильтру, пусть: my_filter_name и применим его так:

// Функция, в которой применяется фильтр 'my_filter_name'
function text( $text ){
	// обрабатываем переданный текст - удалим html теги
	$text = strip_tags( $text );

	// теперь, возвращаем текст через фильтр.
	// Если к фильтру не прикреплена ни одна функция, то текст просто 
	// вернется как есть, т.е. строка ниже будет эквивалентна "return $text;"
	return apply_filters('my_filter_name', $text );
}

// Создадим функцию для фильтра
function my_filter_function( $text ){
	// обрежем текст до 30 знаков и вернем его
	return mb_substr( $text, 0, 30 ) .'...';
}
// Прикрепим функцию к фильтру 'my_filter_name'
add_filter('my_filter_name', 'my_filter_function');

// Внимание, сейчас вылетит птичка :)

// Теперь, при вызове text(), функция удалит из текста html теги — это сделает она сама с помощью strip_tags(). 
// А дальше обрежет текст — это сделает фильтр, с помощью функции my_filter_function()
echo text( 'Lorem <b>Ipsum</b> is simply dummy text of the printing and typesetting industry.' );
// выведет: Lorem Ipsum is simply dummy te...

Фильтров в WordPress много и вы наверняка с ними встречались в темах и плагинах. Одни из самых популярных это: the_content, body_class, sanitize_user, comment_form и т.д.

к началу

Как работают события в WordPress

Для работы события используются две функции:

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

  2. add_action() — добавляет/прикрепляет функции к событию, которое вызывается с помощью do_action(). Функция должна прикрепляться к событию до того, как событие произойдет. Нужно это, чтобы во время срабатывания события PHP функции уже были прикреплены к событию.

Пример

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

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

// создадим функцию для события
function my_action_function( $text ){
	echo 'Событие "my_action" сработало сейчас.';
}
// Прикрепим функцию к событию 'my_action'. Это можно сделать в другом файле
// главное до того как событие сработает.
add_action('my_action', 'my_action_function');

// Вызов самого события. Вставляем эту строку в то место темы где нужно,
// чтобы сработала прикрепленная к нему функция
do_action('my_action');

С событиями вы тоже встречались их много и одни из самых популярных это: wp_head, wp_footer.

к началу

Приоритеты выполнения функций

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

// привяжем функции к хуку
add_action('my_hook', function(){ echo 1; } );
add_action('my_hook', function(){ echo 2; } );
add_action('my_hook', function(){ echo 3; } );

// выполним хук
do_action('my_hook'); // выведет 123

Но, если нужно изменить порядок, то мы может указать приоритет в третьем параметре add_action() или add_filter():

// привяжем функции к хуку
add_action('my_hook', function(){ echo 1; }, 15 );
add_action('my_hook', function(){ echo 2; }, 10 ); // можно не указывать 10 - по умолчанию
add_action('my_hook', function(){ echo 3; }, 5 );

// выполним хук
do_action('my_hook'); // выведет 321

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

Если приоритет не указан, как в первом примере, то он равен 10.

Для фильтров приоритеты работают точно также.

к началу

Передача дополнительных параметров

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

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

$str = apply_filters('my_filter', $str, $data1, $data2 );

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

add_filter('my_filter', 'my_filter_function', 10, 3 ); // 3 - кол. параметров

Тут, 10 - приоритет, а 3 - количество параметров, которые получит функция my_filter_function(). Т.е. функция фильтра будет такая:

function my_filter_function( $str, $data1, $data2 ){
	// фильтруем $str. 
	// Можем использовать $data1, $data2
	return $str;
}

У событий все работает аналогично:

// прикрепляем функцию
function my_action_function( $data1, $data2, $data3 ){
	// делаем что либо во время события
	// Можем использовать $data1, $data2, $data3 
}
add_filter('my_action', 'my_action_function', 10, 3 );

// вызываем событие
do_action('my_action', $data1, $data2, $data3 );
к началу

Как удалить хук: фильтр или событие

Для удаления функции привязанной к фильтру или событию, используется одна из функций: remove_action() и remove_filter().

Для справки. Это полностью одинаковые функции и обе они удаляют хук, а фильтр это или событие, в данном случае, значения не имеет. Так, и события и фильтры мы можем удалять используя только функцию remove_filter() или только remove_action(). Но для понятности и лучшей читаемости кода, все же лучше фильтры удалять с помощью remove_filter(), а события с помощью remove_action().

Для удаления хука (прикрепленной к событию/фильтру функции), нужно знать:

  • название хука, например wp_footer;
  • название прикрепленной функции, например my_action_function из примера выше;
  • приоритет выполнения хука, если он был установлен при создании хука. Если при создании приоритет не был установлен, то он равен 10 и при удалении его указывать не обязательно

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

Пример удаления хука

Допустим где-то в коде, например, в плагине, к событию wp_footer прикреплена функция my_action_function, которая выводит текст в подвале темы:

add_action('wp_footer', 'my_action_function');
function my_action_function( $text ){
	echo 'Это текст в подвале!';
}

Теперь, например, в теме нам нужно удалить это событие, чтобы текст в подвале не выводился. Для этого в functions.php темы можно прописать такой код:

remove_action('my_action', 'my_action_function');

Важный момент: код плагина подключается до подключения файла темы functions.php. А значит, в момент удаления хука: remove_action(), событие уже добавлено в общий массив событий и мы можем его от туда удалить.

Еще пример удаления хука

Демонстрация добавления и удаления хука в одном коде:

// добавляем функцию к событию my_action
add_action('my_action', 'my_action_function');
function my_action_function( $text ){
	echo 'Привет!';
}

// вызываем событие
do_action('my_action'); //> Привет!

// теперь удаляем добавленное ранее событие
remove_action('my_action', 'my_action_function');

// вызываем событие еще раз
do_action('my_action'); // ничего не выведет...

Примеры удаления хуков с приоритетами и добавленных через PHP класс

// Пример -----------------------------
// Простое удаление
add_filter('my_filter', 'function_name');    // так добавлен
remove_filter('my_filter', 'function_name'); // так нужно удалять

// Пример -----------------------------
// Удаление с приоритетом
add_filter('my_filter', 'function_name', 99);    // так добавлен
remove_filter('my_filter', 'function_name', 99); // так нужно удалять - приоритет должен совпадать...

// Пример -----------------------------
// Удаление статического метода класса
add_filter('my_filter', array('My_Class', 'method_name'), 15 );   // так добавлен
remove_filter('my_filter', array('My_Class', 'method_name'), 15); // так нужно удалять - приоритет должен совпадать...

// Пример -----------------------------
// Удаление не статического метода класса, который добавлен с использованием $this
class A{
	function __construct(){
		add_action('my_action', array( & $this, 'method_name'), 15 );   // так добавлен
	}

	function method_name(){  echo 'Привет!';  }
}

$class = new A; // экземпляр

// для удаления нужно найти переменную в которую был сохранен экземпляр класса при создании, сейчас это $class
remove_action('my_action', array( $class, 'method_name'), 15 );   // так нужно удалять

// Пример -----------------------------
// Удалить хук добавленный лямбда-функцией (замыканием) невозможно!
add_action('my_action', function(){  echo 'Привет!';  } );   // так добавлен
// никак не удалить, даже так:
remove_action('my_action', function(){  echo 'Привет!';  });
к началу

Все функции хуков

Функция Описание
add_action Регистрирует хук-событие. При регистрации указывается PHP функция, которая сработает в момент события, которое вызывается с помощью do_action().
did_action Получает число, сколько раз было выполнено данное событие (хук).
do_action Создает событие (зацепку для произвольной функции). Чтобы функция сработала в момент события её нужно подключить к этому событию с помощью функции add_action().
do_action_ref_array Создает хук (действие) для зацепки функции. Аргументы передаются из массива.
has_action Проверяет была ли зарегистрирована функция для хука (действия).
remove_action Удаляет функцию прикрепленную к указанному хуку (событию).
   
add_filter Прикрепляет указанную PHP функцию к указанному хукe-фильтру. Так, во время срабатывания фильтра значение будет обработано указанной PHP функцией.
apply_filters Применяет прикрепленную к указанному фильтру PHP функцию. Прикрепляется функция с помощью add_filter().
apply_filters_ref_array Выполняет функции прикрепленные к указанному хуку (фильтру). Параметры передаются в массиве.
current_filter Получает название текущего действия или фильтра.
doing_filter Проверяет обрабатывается ли указанный хук (фильтр или событие), в текущий момент.
has_filter Проверяет была указана дли для фильтра какая-нибудь функция, т.е. имеется ли указанный хук.
remove_all_filters Удаляет все хуки у указанного фильтра.
remove_filter Удаляет указанную функцию прикрепленную к указанному фильтру.
к началу

Вспомогательные функции для фильтров

В WordPress есть специальные функции, которые упрощают работу с фильтрами.

Например, мы может отключить все стандартные виджеты WordPress с помощью фильтра load_default_widgets, так:

function is_load_default_widgets(){
	return false;
}
add_filter( 'load_default_widgets', 'is_load_default_widgets' );

Или можно не создавать отдельную функцию которая вернет false, а использовать уже готовую функцию из ядра WordPress: __return_false():

add_filter( 'load_default_widgets', '__return_false' );

Чтобы было понятнее как это работает, давайте посмотрим на вызов фильтра load_default_widgets:

function wp_maybe_load_widgets() {
	if ( ! apply_filters( 'load_default_widgets', true ) )
		return;

	require_once( ABSPATH . WPINC . '/default-widgets.php' );

	add_action( '_admin_menu', 'wp_widgets_add_menu' );
}

При вызове функции wp_maybe_load_widgets() срабатывает фильтр. По умолчанию он всегда возвращает true и условие не выполняется — виджет подключаются. А в примерах выше мы возвращаем false и условие выполняется — виджеты не подключаются.

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

Аналогичный пример

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

// отключим публикацию по xmlrpc
add_filter( 'xmlrpc_enabled', '__return_false' );

Еще один пример

Закроем возможность сброса пароля, с помощью фильтра allow_password_reset:

add_filter( 'allow_password_reset', '__return_false' );

Теперь все пользователи не смогут сбрасывать пароли на сайте.

Кроме __return_false(), есть и другие вспомогательные функции, которые просто возвращают готовое значение. Вот их список:

к началу

Получение списка всех хуков WordPress

Уж не знаю зачем, но такое может понадобится. В процессе разработки или при поиске ошибок...

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

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

function hooks_list( $tag = false ){
	global $wp_filter;

	if ( $tag ) {
		$hook[$tag]=$wp_filter[$tag];
		if (!is_array($hook[$tag])) {
			trigger_error("Nothing found for '$tag' hook", E_USER_WARNING);
			return;
		}
	}
	else {
		$hook = $wp_filter;
		ksort( $hook );
	}

	echo '<pre>';
	foreach( $hook as $tag => $priority ){
		echo "\nхук\t<b>$tag</b>\n";
		ksort( $priority );
		foreach( $priority as $priority => $function ){
			echo $priority;
			foreach( $function as $name => $properties)
				echo "\t$name\n";
		}
	}
	echo '</pre>';
}

hooks_list();

/* Получим список такого формата:

хук wp_enqueue_scripts
10  lambda_2
99  theme_scripts_styles

хук wp_footer
0   0000000072b7ec0d00002b862c2211a0enqueue_jquery_if_need
10  0000000072b7edb400002b862c2211a0footer_scripts
	0000000072b7eb7b00002b862c2211a0main_js
20  wp_print_footer_scripts
99  0000000072b7ec0d00002b862c2211a0add_script_to_footer
	0000000072b7eb1600002b862c208180
	question_close_ajax_js
	add_question_rating_ajax_js
	add_comment_rating_ajax_js
999 0000000072b7edb600002b862c2211a0footer_script
1000    wp_admin_bar_render
9999999999  0000000072b7eb0b00002b862c208180

... и т.д. ...
*/

А так выглядит элемент массива в самой переменной $wp_filter:

global $wp_filter;

print_r( $wp_filter );

/*
	[wp_title] => WP_Hook Object
		(
			[callbacks] => Array
				(
					[10] => Array
						(
							[wptexturize] => Array
								(
									[function] => wptexturize
									[accepted_args] => 1
								)

							[convert_chars] => Array
								(
									[function] => convert_chars
									[accepted_args] => 1
								)

							[esc_html] => Array
								(
									[function] => esc_html
									[accepted_args] => 1
								)

						)

					[11] => Array
						(
							[capital_P_dangit] => Array
								(
									[function] => capital_P_dangit
									[accepted_args] => 1
								)

						)

				)

			[iterations:WP_Hook:private] => Array
				(
				)

			[current_priority:WP_Hook:private] => Array
				(
				)

			[nesting_level:WP_Hook:private] => 0
			[doing_action:WP_Hook:private] => 
		)

	[widget_title] => WP_Hook Object
		(
		............... и т.д.
*/
к началу

Как получить функции прикрепленные к указанному хуку?

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

Чтобы получить такой список, воспользуемся глобальной переменной $wp_filters. Чтобы вам не возиться, используйте вот такую готовую функцию:

/**
 * Выводит список функций прикрепленных к указанному хуку
 * @param (str) $hook Название хука, функции которого нужно вывести.
 */
function print_filters_for( $hook ){
	global $wp_filter;
	$data = isset( $wp_filter[$hook] ) ? $wp_filter[$hook] : "Хук `$hook` не найден...";

	echo '<pre>', print_r( $data, 1 ) .'</pre>';
}

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

Например, получим все функции добавленные к событию wp_footer:

print_filters_for('wp_footer');

/* Выведет:

WP_Hook Object (

	[callbacks] => Array (

		[0] => Array (
			[echo_ads_tpls] => Array (
				[function] => echo_ads_tpls
				[accepted_args] => 1
			)
		)

		[20] => Array (
			[wp_print_footer_scripts] => Array (
				[function] => wp_print_footer_scripts
				[accepted_args] => 1
			)
		)

		[99] => Array (
			[question_close_ajax_js] => Array (
				[function] => question_close_ajax_js
				[accepted_args] => 1
			)

			[add_question_rating_ajax_js] => Array (
				[function] => add_question_rating_ajax_js
				[accepted_args] => 1
			)

			[add_comment_rating_ajax_js] => Array (
				[function] => add_comment_rating_ajax_js
				[accepted_args] => 1
			)

			[textarea_tab_on_tab_click] => Array (
				[function] => textarea_tab_on_tab_click
				[accepted_args] => 1
			)

			[add_to_bookmark_js] => Array (
				[function] => add_to_bookmark_js
				[accepted_args] => 1
			)
		)

		[1000] => Array (
			[wp_admin_bar_render] => Array (
				[function] => wp_admin_bar_render
				[accepted_args] => 1
			)
		)
	)

	[iterations:WP_Hook:private] => Array()
	[current_priority:WP_Hook:private] => Array()
	[nesting_level:WP_Hook:private] => 0
	[doing_action:WP_Hook:private] =>
)
*/

Где в индексе callbacks будут все функции прикрепленные к хуку, в порядке приоритета их вызова...

Как работают хуки в WordPress (фильтры и события) 23 комментария
Полезные 1 Вопросы 1 Все
  • yura
    @

    Добрый день! У Вас в примере по добавлению фильтра есть такой код:

    function is_load_default_widgets(){
    	return false;
    }
    add_filter( 'load_default_widgets', 'is_load_default_widgets' );

    Он должен отключать подгрузку стандартных виджетов вордпресса и добалвение пункта меню ВИДЖЕТЫ в админке.

    Я добавляю этот код в functions.php в тему, но , похоже, он не срабатывает.
    Подскажите, в чем может быть проблема?

    Заранее благодарю!

    Ответить1.1 года назад #
    -1
    • Kama4394

      Там чуть ниже есть

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

      Ответить1.1 года назад #
      • yura
        @

        Благодарю за быстрый ответ! Да, я видел это замечание.
        Дело в том, что функция unregister_widget() не отменяет подгрузку самих классов виджетов. А я у себя в теме хочу создать виджет с таким же классом, как и стандартный, но с измененным HTML выводом (нужно это для того, что средства автоматического тестирования виджетов вордпресса ищут стандартные виджеты по имени класса (плагин monsterwidget) ).
        Поэтому я хочу отключить загрузку файлов с классами стандартных виджетов.
        Сделать это, теоретически, можно либо способом, описанным Вами (почему-то неработающем) или, в теории, таким способом:

        remove_action( 'plugins_loaded', 'wp_maybe_load_widgets', 0 );

        Однако он тоже, почему-то срабатывает только если я прописываю его в файле wp-includes/default-filters.php, что, разумеется не годится. А в теме не срабатывает.

        Ответить1.1 года назад #
        • Kama4394

          Не срабатывает в functions.php потому что этот файл подключается после того как сработает событие plugins_loaded... Вам нужно подключиться до события

          add_action( 'plugins_loaded', 'wp_maybe_load_widgets', 0 );

          Это можно сделать через обычный плагин или через mu-plugins

          Но тут проблема в том, что при отключении виджетов хуком 'load_default_widgets' вы отключите стандартные виджеты и вообще меню виджетов админ-панели, по сути отключатся все возможные виджеты...

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

          Как вариант вы можете отключить виджеты примером из этой статьи и включить меню виджетов добавив отключенное событие отдельно:

          add_action( '_admin_menu', 'wp_widgets_add_menu' );

          Короче говоря, вам надо созать плагин с таким кодом:

          remove_action( 'plugins_loaded', 'wp_maybe_load_widgets', 0 );
          add_action( '_admin_menu', 'wp_widgets_add_menu' );
          Ответить1.1 года назад #
          • yura
            @

            Благодарю, с экшеном Вы прояснили.
            А почему же не срабатывает фильтр? В фильтрах тоже должна быть соблюдена какая-то очередность его объявления?

            Ответить1.1 года назад #
            • Kama4394

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

              Ответить1.1 года назад #
              • yura
                @

                Насчет события я понял. Хотя в целом, довольно трудно разобраться с очередностью событий - не нашел документации на этот счет. Может быть, не там искал.
                Я так понял, с фильтрами - та же история? Код

                    if ( ! apply_filters( 'load_default_widgets', true ) ) {
                		return;
                	}

                нужно вставлять в плагин, чтоб он сработал в нужный момент, в теме уже поздно?

                Благодарю за ответы!

                Ответить1.1 года назад #
                • yura
                  @

                  Виноват. Имел ввиду вот этот код:

                  add_filter( 'load_default_widgets', '__return_zero' );
                  Ответить1.1 года назад #
                  -1
              • Kama4394

                Щас проверил свой код, там еще надо так дополнить его:

                remove_action( 'plugins_loaded', 'wp_maybe_load_widgets', 0 );
                // включим событие отключенное в wp_maybe_load_widgets
                add_action( '_admin_menu', 'wp_widgets_add_menu' );
                
                // чтобы не регистрировались виджеты классов которых теперь вообще нет...
                remove_action( 'init', 'wp_widgets_init', 1 );
                
                // включим событие отключенное в wp_widgets_init
                add_action( 'init', 'my_wp_widgets_init', 1 );
                function my_wp_widgets_init(){
                	if ( !is_blog_installed() ) return;
                
                	/**
                	 * Fires after all default WordPress widgets have been registered.
                	 *
                	 * @since 2.2.0
                	 */
                	do_action( 'widgets_init' );
                }

                Это должен быть либо плагин либо mu-plugin. Он кроме того что отключает все базовые виджеты, также отключает подключение всех файлов виджетов и с ним становится возможными создать свои виджеты с базовыми названиями виджетов вроде: WP_Widget_Pages, WP_Widget_Search и т.д.

                Ответить1.1 года назад #
                • yura
                  @

                  Огромное спасибо.
                  Значит, без плагина не обойтись даже с фильтром на 'load_default_widgets' ...
                  Да, я видел, что помимо отключения подгрузки стандартных виджетов нужно еще и отключать их регистрацию, иначе - ругня на несуществующий класс, и что нужно будет руками добавлять пункт меню "Виджеты".
                  Всё таки довольно сложно новичку разобраться, какие экшены и фильтры сработают из файлов темы, какие - только из плагинов.
                  Еще раз благодарю! Если б не Вы, копался бы еще неизвестно сколько.

                  Ответить1.1 года назад #
  • Andrey
    @

    Здравствуйте, Тимур! Полночи не спал, но так и не понял, где находится один фильтр — manage_nav-menus_columns. Я не смог найти его в файлах ядра, как ни искал. add_filter( 'manage_nav-menus_columns'... есть,
    а вот apply_filters( 'manage_nav-menus_columns'... не нашел. Где он вообще устанавливается? Снова ведь спать не смогу. Спасибо!

    Ответитьгод назад #
    • Kama4394

      Откуда вы про этот фильтр узнали?

      Ответитьгод назад #
      • Andrey
        @

        Он есть в плагине Menu Image. Я решил разобраться, как он работает, чтобы использовать принцип в своей теме для сайта. И не понял... Прошерстил файлы самого wordpress, и он там используется несколько раз. То есть это не пользовательский фильтр плагина. Еще он упоминается здесь: http://hookr.io/filters/manage_nav_menus_columns/

        Ответитьгод назад #
  • Сергей

    Для чего в примере

    function wp_maybe_load_widgets() {
    	if ( ! apply_filters( 'load_default_widgets', true ) )
    		return;
    
    	require_once( ABSPATH . WPINC . '/default-widgets.php' );
    
    	add_action( '_admin_menu', 'wp_widgets_add_menu' );
    }

    восклицательный знак перед apply_filters? Он ведь меняет возвращаемое значение фильтром с true на false. К чему это тут? Ведь по умолчанию фильтр возвращает true и сам переводит его в false, а ведь false должно возвращаться из примера выше.

    Ответитьгод назад #
    • campusboy1577 cайт: wp-plus.ru
      @

      Код верный. Переводим его на человеческий язык:
      1) Загрузить дефолтные виджеты? Да
      2) Если бы не !, то сработало условие return и дальше ничего не загрузилось, но у нас есть ! и он "Да", меняет на "Нет", потому return не срабатывает и..
      3) Идёт подгрузка дефолтных виджетов.

  • Антон

    Благодарю!

  • TaNikTa
    @

    Здравствуйте, Тимур!
    Переписываю плагин WP User Avatar, который загружает аватары пользователей стандартно как WP в uploads, а я добиваюсь, чтоб грузил в отдельную папку и это я реализую функцией:

    function my_upload_dir($upload) {
    	$upload['subdir']   = '';
    	$upload['basedir']  = WP_CONTENT_DIR;
    	$upload['baseurl']  = WP_CONTENT_URL;
    	$upload['path']     = $upload['basedir'] . '/wp_user_avatar';
    	$upload['url']      = $upload['baseurl'] . '/wp_user_avatar';
    	return $upload;
    }

    Перед функцией вставляю фильтр:

    add_filter('upload_dir', 'my_upload_dir');

    А после функции:

    $upload = wp_upload_dir();
    remove_filter('upload_dir', 'my_upload_dir');

    Но remove_filter тупо отменяет add_filter и все грузится в uploads, а если remove_filter не ставить, то вообще все медиа грузятся сюда: $upload['url'] = $upload['baseurl'] . '/wp_user_avatar';
    Не пойму почему remove_filter не срабатывает, вроде все последовательно, вот код целиком:

    add_filter('upload_dir', 'my_upload_dir');
    function my_upload_dir($upload) {
    	$upload['subdir']   = '';
    	$upload['basedir']  = WP_CONTENT_DIR;
    	$upload['baseurl']  = WP_CONTENT_URL;
    	$upload['path']     = $upload['basedir'] . '/wp_user_avatar';
    	$upload['url']      = $upload['baseurl'] . '/wp_user_avatar';
    	return $upload;
    }
    $upload = wp_upload_dir();
    remove_filter('upload_dir', 'my_upload_dir');

    Бьюсь уже несколько дней, может что не так делаю?
    Подскажите, в чем может быть проблема?

    Заранее огромное спасибо!

    1
  • Turgenoid cайт: thegazer.ru
    // создадим функцию для события
    function my_action_function( $text ){
    	echo 'Событие "my_action" сработало сейчас.';
    }
    // Прикрепим функцию к событию 'my_action'. Это можно сделать в другом файле
    // главное до того как событие сработает.
    add_filter('my_action', 'my_action_function');
    
    // Вызов самого события. Вставляем эту строку в то место темы где нужно,
    // чтобы сработала прикрепленная к нему функция
    do_action('my_action');

    А почему add_filter, а не add_action?

    Ответитьмесяц назад #

Здравствуйте, !

Ваш комментарий