WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

add_filter() WP 0.71

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

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

Функция не делает никаких проверок: существует ли прикрепляемая функция или передается ли название функции в виде строки и т.д.. Сделано это, чтобы add_filter() работала максимально быстро.

Базовый список фильтров смотрите здесь и тут весь список фильтров

О фильтрах и событиях читайте в этой заметке: как работают хуки в WordPress

Является основой для: add_action()
✈ 1 раз = 0.000015с = очень быстро | 50000 раз = 0.05с = скорость света | PHP 7.0.8, WP 4.7

Хуков нет.

Возвращает

Всегда true.

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

add_filter( $tag, $function_to_add, $priority, $accepted_args );
$tag(строка) (обязательный)
Название фильтра, для которого будет срабатывать функция определенная в параметре $function_to_add.
По умолчанию: нет
$function_to_add(строка) (обязательный)
Название функции, которая будет срабатывать для указанного в предыдущем параметре фильтра. Название функции нужно указывать в виде строки: 'название_функции'. Для функций внутри классов указываем массив: array('название_класса', 'название_функции'), подробнее читаем тут (знания англ. приветствуются).
По умолчанию: нет
$priority(число)
Приоритет выполнения функций для одного и тоже фильтра. Чем больше число, тем позднее будет выполнятся функция: например, сначала 10 потом 20. Функции с одинаковым приоритетом, будут выполнятся в порядке их добавления к массиву фильтров.
По умолчанию: 10
$accepted_args(число)
Количество аргументов передаваемых фильтром функции. Некоторые фильтры могут передавать больше чем 1 аргумент, допустим - 2, для таких случаев нужно указывать 2 в этом параметре.
По умолчанию: 1

Примеры

#1. Обычный пример, показывающий как можно добавить любую надпись в конец каждой статьи, через фильтр the_content:

add_filter( 'the_content', 'add_text_to_content' );
function add_text_to_content($content){
	$out = $content . "<p>При копировании статьи, ставьте обратную ссылку, пожалуйста!</p>";
	return $out;
}

#2. Изменения блока «подпись картинки» (сaption)

Пример изменения подписи у картинок ([сaption]) под стандарты HTML 5. Функция меняющая контент цепляется на фильтр img_caption_shortcode, который отвечает за преобразование шоткода [сaption] в контенте статьи. Чтобы получить все 3 параметра, передаваемые фильтром, укажем аргумент $accepted_args - 3:

add_filter( 'img_caption_shortcode', 'my_img_caption_shortcode_filter', 10, 3 );
/**
 * Фильтр заменяет шоткод [сaption] под стандарты HTML5
 *
 * @Возвращает HTML текст описывающий тег figure
 **/
function my_img_caption_shortcode_filter( $val, $attr, $content = null ){
	extract(shortcode_atts(array(
		'id'    => '',
		'align' => '',
		'width' => '',
		'caption' => ''
	), $attr));

	if ( 1 > (int) $width || empty($caption) )
		return $val;

	$capid = '';
	if ( $id ) {
		$id = esc_attr($id);
		$capid = 'id="figcaption_'. $id . '" ';
		$id = 'id="' . $id . '" aria-labelledby="figcaption_' . $id . '" ';
	}

	return '<figure ' . $id . 'class="wp-caption ' . esc_attr($align) . '" style="width: '
	. (10 + (int) $width) . 'px">' . do_shortcode( $content ) . '<figcaption ' . $capid 
	. 'class="wp-caption-text">' . $caption . '</figcaption></figure>';
}

#3. Функцию можно передавать как анонимную:

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

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

add_filter( 'the_title', function( $title ){
	return '<b>'. $title. '</b>';
});

#4. Внутри классов функцию фильтра нужно указывать через массив:

Первое значение массива это экземпляр класса, а второе название метода этого класса.

add_filter( 'media_upload_newtab', array( $this, 'media_upload_mycallback') );

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

add_filter( 'media_upload_newtab', array( 'My_Class', 'media_upload_mycallback') );

Заметки

  • Global. Массив. $wp_filter A multidimensional array of all hooks and the callbacks hooked to them.

Список изменений

С версии 0.71 Введена.

Код add filter: wp-includes/plugin.php WP 5.2.2

<?php
function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
	global $wp_filter;
	if ( ! isset( $wp_filter[ $tag ] ) ) {
		$wp_filter[ $tag ] = new WP_Hook();
	}
	$wp_filter[ $tag ]->add_filter( $tag, $function_to_add, $priority, $accepted_args );
	return true;
}

Cвязанные функции

Из метки: Фильтры (хуки)

Еще из раздела: Хуки: события, фильтры

33 коммента
Полезные 4 Вопросы 1 Все
  • art

    Кама привет.
    $priority (число)
    Приоритет выполнения функций для одного и тоже фильтра. Чем больше число, тем позднее будет выполнятся функция: например, сначала 20 потом 10.

    сначала 20 потом 10.
    очепятка?

    Ответить7 лет назад #
    • Kama7534
      add_filter('the_content', function($cont){return '10--'.$cont;}, 10);
      add_filter('the_content', function($cont){return '20--'.$cont;}, 20);
      
      echo apply_filters('the_content', '...текст...');
      
      // вернет: 20--10--...текст...

      Да, вы правы, опечатка! Спасибо, поправил.

      Ответить7 лет назад #
  • Макс158 cайт: wp-panda.com

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

    Ответить5.7 лет назад #
    • Kama7534

      Если там фильтра нет, то никак, наверное. Попробуйте назвать функцию точно также, если там стоит проверка на существование такой функции, то может ваша сработает.

      Ответить5.7 лет назад #
      • Макс158 cайт: wp-panda.com

        фильтра нет, проверки нет через runkit_function_redefine() не вариант, похоже не судьба))

        Ответить5.7 лет назад #
  • Здравствуйте!
    подскажите, а если мне нужно добавить результат моейфункции в конец the_content();?
    у меня не выходит - результат выводится перед контентом.

    Ответить5.6 лет назад #
    • Kama7534

      $priority параметр поставьте например 99 или 999 или вообще 9999, что значит что ваша функция будет выполняться после остальных.

      add_filter('the_content', 'add_text_to_content', 99);
      Ответить5.6 лет назад #
      • Alex cайт: bardline.info

        А как добавить текст в конец статьи, но чтобы он не добавлялся в rss?

        Ответить5.2 лет назад #
        • Kama7534

          Подключать текст если срабатывает условие:

          <?php
          add_filter('the_content', 'add_text_to_content', 99);
          
          function add_text_to_content( $text ){
          	if( is_feed() )
          		return;
          
          	// дальше код вашей функции
          }
          ?>
          Ответить5.2 лет назад #
  • Есть такая функция:

    add_filter('wp_nav_menu', 'add_rel_nofollow_to_wp_list_categories');
    function add_rel_nofollow_to_wp_list_categories($a) {
    return str_replace('<a ', '<a rel="nofollow" ', $a);
    }

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

    Ответить5.5 лет назад #
    • Kama7534
      add_filter('wp_nav_menu', 'add_rel_nofollow_to_wp_list_categories');
      function add_rel_nofollow_to_wp_list_categories( $a ) {
      	if( ! is_front_page() )
      		return str_replace('<a ', '<a rel="nofollow" ', $a);
      
      	return $a;
      }
      1
      Ответить5.5 лет назад #
  • Антон cайт: aktv.ru

    Артём, я не пойму. Вот например этот же код:

    add_filter('tratata', 'add_text_to_content', 10, 2);
    function add_text_to_content($a, $b){
    	$out = $content . "<p>При копировании статьи, ставьте обратную ссылку, пожалуйста!</p>";
    	return $out;
    }

    Т.е. мы на tratata вешаем функцию адд_текст с 2 аргументами. А аргументы-то для этой функции где берутся?

    Ответить5 лет назад #
    • Kama7534

      Какой Артем?

      Аргументы передаются в момент вызова фильтра.

      1
      Ответить5 лет назад #
  • Михаил

    Почему не могу перезаписать rel
    Для примера просто на текст хочу заменить

    add_filter('rel_canonical', 'rel_up');
    
    function rel_up( ) {
    
    	echo "Это займет несколько строк. Переводы строки тоже выводятся";
    }
    Ответить4.1 года назад #
    • campusboy3409 cайт: www.youtube.com/c/wpplus

      Потому что нужно так:

      add_filter('rel_canonical', 'rel_up');
      
      function rel_up( $text ) {
      	$text = "Это займет несколько строк. Переводы строки тоже выводятся";
      	return $text;
      }
      Ответить4.1 года назад #
    • Kama7534

      По-момему в ВП нет фильтра 'rel_canonical' no

      Ответить4.1 года назад #
  • Михаил

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

    add_filter('the_content', function($content)
    {
      //......
       return $content;
    });
    Ответить3.4 года назад #
    • Михаил

      ОК, решил

      global $post;
       if ($post->post_type == 'post') {
      //..........
      }
      Ответить3.4 года назад #
  • spoonyto

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

    	add_filter( 'default_content', 'custom_editor_content' );
    	function custom_editor_content( $content ) {
    		$content = 'Выведи счастье по умолчанию';
    
    		return $content;
    	}
    
    add_editor_style( 'editor-style.css' );

    Вот что я пытаюсь сделать

    add_filter( 'default_content', 'custom_editor_content' );
    	function custom_editor_content( $content ) {
    		$content = '
    		<div class="schactie">Выведи счастье по умолчанию</div>
    		<div id="contact_form_pop"><?php echo do_shortcode('[contact-form-7 id="65"]'); ?></div> 
    		';
    
    		return $content;
    	}

    Как понимаете всё условно. Но что нужно - Выводить в рамках предопределенного стиля редактора - ещё и элементы с использованием вставок - функций или кусочков кода php. Как только я добавляю второй вариант, сайт ложиться белым экраном смерти. Прошу прощения за кривые объяснения или незнание основных. Подскажите, как можно реализовать такой функционал?

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

      Измените это:

      <div id="contact_form_pop"><?php echo do_shortcode('[contact-form-7 id="65"]'); ?></div>

      на

      <div id="contact_form_pop">'. do_shortcode('[contact-form-7 id="65"]') .'</div>
      3
      Ответить3.4 года назад #
      • spoonyto

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

            add_filter( 'default_content', 'custom_editor_content' );
        	function custom_editor_content( $content ) {
        		$content = '
        	<div class="under-conference">
        	<div class="registration"><a href="#contact_form_pop" class="fancybox"><img src="<?php bloginfo('template_url'); ?>/images/registration.png"></a> 
        	<div style="display:none" class="fancybox-hidden"> 
        	<div id="contact_form_pop"><?php echo do_shortcode('[contact-form-7 id="65"]'); ?></div> 
        	</div><div class="regtext">Регистрация</div></div>
        	<div class="request"><a href="#contact_form_pop1" class="fancybox"><img src="<?php bloginfo('template_url'); ?>/images/request.png"></a>
        	<div style="display:none" class="fancybox-hidden"> 
        	<div id="contact_form_pop1"><?php echo do_shortcode('[contact-form-7 id="66"]'); ?></div></div>
        	<div class="reqtext">Программа</div></div>
        	</div>
        		<div class="content-col-all">
        		<div class="content-col-main">Main text  </div>
        		<div class="content-col-1">This event will allow to  </div>
        		<div class="content-col-2">Conference audience  </div>
        		<div class="content-col-partners"><div class="partners1">Partner1 </div><div class="partners2">Partner2 </div><div class="partners3">Partner3 </div></div>
        		<div class="content-col-mpartners"><div class="mpartners1">mPartner1 </div><div class="mpartners2">mPartner2 </div><div class="mpartners3">mPartner3 </div>
        		<div class="mpartners4">mPartner4 </div><div class="mpartners5">mPartner5 </div></div>
        		<div class="content-col-contacts">Contacts  </div>
        		</div>
        		';
        
        		return $content;
        	}

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

        Ответить3.4 года назад #
        • Антон cайт: qazomardok.ru

          Вам правильно ответили. У вас синтаксические и логические ошибки в коде. Вы объявляете переменную $content ($content = 'содержание переменной';), и в её содержании начинаете делать что попало:

          1. то закрывать/открывать php, и печатать(!) html

          2. то выполнять функции (у вас получается ТЕЛЕГА = крутить колесо, согласитесь - бред). 3. То используете одинарные кавычки при том что ими же и обволакиваете содержимое переменной, в итоге у вас $content заканчивается при первом же прочтении bloginfo('

          Белый экран в этом случае лезет из-за всех этих ошибок. Потому что у вас при применении этого кода на экран начинает выводиться текст (ошибка php или url шаблона сайта). А так как функция выполняется ДО оправки заголовков вордпрессом (header), то и поучаете.

          1
          Ответить3.4 года назад #
        • Антон cайт: qazomardok.ru

          Чтоб вам проще был понять, маленькая подсказка: есть функция bloginfo(), которую вы используете, - она (внимание) выводит, печатает(!) на экран. А есть get_bloginfo(), которая не печатает, а просто возвращает значение. Вы же пытаетесь сделать так:

          Переменная = 'тексттексттекст РАСПЕЧАТЬ_НА_ЭКРАН('url шаблона') РАСПЕЧАТАТЬ ШОРТКОД текст';

          А надо:

          Переменная = 'текстекстекстт ' . ПОЛУчИТЬ("url шаблона"). ' текстекст ' . ШОРТКОД . ' текст ';
          2
          Ответить3.4 года назад #
          • spoonyto

            Спасибо большое!!! Всё помогло, теперь понял мысль, шагнул глубже в области знаний.

            1
            Ответить3.4 года назад #
  • @ Алексей

    подскажите пожалуйста можно ли сделать чтобы add_filter() применялась ко всем страницам кроме определенной категории ?

    Ответить3 года назад #
    • campusboy3409 cайт: www.youtube.com/c/wpplus
      if ( !is_category('9') ){
       add_filter( $tag, $function_to_add, $priority, $accepted_args );
      }

      Восклицательный знак означает "не", то есть, если эта НЕ рубрика с ID 9, то включать фильтр.

      Справка: условный тег is_category()

      1
      Ответить3 года назад #
  • Виктор

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

    function true_img($html, $id, $caption, $title, $align, $url, $size, $alt) {
    
    	$out = '<div>' . $html. '</div>';
    	return $out; 
    }
    
    add_filter('image_send_to_editor', 'true_img');

    Попробовал пример из статьи (the_content), работает.

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

      Причина по сути одна, фильтр не включается... Решение:

      • Попробуй пораньше подключить фильтр, например в плагине или mu-плагине.
      • Убедись что нет лишних условий которые могут отключить подключение фильтра. Что-то мне подсказывает что этот фильтр срабатывает при аякс запросе...
      1
      Ответить2.4 года назад #
      • Виктор

        Заработало! Поставил код в начале functions.php. Спасибо!

        Ответить2.4 года назад #
Здравствуйте, !     Войти . Зарегистрироваться