Очередной блог фрилансера

коротко и полезно о веб-разработке

Menu Close

WordPress. Фильтруем HTML в записях и комментариях

Я давно уже наблюдаю мучения читателей, которые пытаются оставить примеры html-разметки в комментариях. К сожалению, в прошлом году, долго не находилось времени, для решения этой проблемы.
Но сегодня, с радостью хочу объявить о том, что проблема наконец-то решена – теперь вы можете использовать любую html-разметку в комментариях, предварительно заключив ее в теги <code>, а если вам интересно как это реализовано, то читайте далее.

Описание проблемы

HTML – это структурированный язык разметки, в котором текст заключается внутри тегов с угловыми скобками. Эти тэги сообщает браузеру, каким образом необходимо структурировать/отобразить информацию, содержащуюся между ними. Одни из самых распространенных тегов – это открывающий и закрывающий тег параграфа (<p>, </p>); они сообщают браузеру, что текст, который находится внутри, является параграфом, в общей структуре документа.

Но что если, вы захотите показать читателям пример html-разметки?

Вы не сможете вывести тэги на экран, просто напечатав их, поскольку браузер решит, что это html-код и не отобразит их. Поэтому, для того чтобы вывести html-код, мы должны использовать специальные угловые скобки. Для вывода таких скобок используется их символьный объект – специальный код, который выведет нужный символ. Этот код может быть как в форме имени, так и в форме числа, можно использовать то, что больше нравится. Например, прямые кавычки “ можно вывести двумя способами – используя объект-имя &quot; или объект-число &#34;.

Левую угловую скобку можно вывести с помощью &lt; или &#60;. В нашем примере, для вывода угловых скобок, мы будем использовать символьные объекты &lt; и &gt;.

Добавляем HTML-код в текст записи WordPress

Теперь, после того как мы разобрались, как отобразить HTML-код на экране, давайте разберемся как нам это использовать в записях WordPress. На первый взгляд все очень просто – нужно всего лишь заменить левые и правые угловые скобки в их символьные эквиваленты. Это хорошо пока у вас одна-две строчки кода, но что делать, если их значительно больше? Существуют различные плагины для решения этой проблемы, но большинство их них требуют дополнительной разметки в статье.

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

С помощью специального фильтра WordPress, мы сможем нормально отображать примеры html-кода в статьях и комментариях, внутри тегов <pre>.

Фильтры WordPress

Из Кодекса:

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

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

Специальный WordPress HTML фильтр

Вот так выглядит код фильтра:

<?php
function mish_code_filter($content_text) {
    $content_text = preg_replace('!(<pre.*?>)(.*?)</pre>!ise', " '$1' .  stripslashes( str_replace(array('<','>'),array('&lt;','&gt;'),'$2') )  . '</pre>' ", $content_text);
    return $content_text;
    }

add_filter('the_content','mish_code_filter', 1, 1);
?>

Теперь, давайте разберем код на части. Сначала мы создаем новую функцию, под названием “mish_code_filter”:

function mish_code_filter($content_text) {
    <!-- function actions -->
    }

Далее, мы описываем, что будет делать функция. В нашем примере, мы используем PHP-функцию preg_replace(), которая будет отыскивать текст внутри тэгов <pre>

$content_text = preg_replace('!(<pre.*?>)(.*?)</pre>!ise',

…и заменять их на зашифрованный текст:

" '$1' .  stripslashes( str_replace(array('<','>'),array('&lt;','&gt;'),'$2') )  . '</pre>' ",

Вторая часть функции preg_replace(), использует две PHP-функции: stripslashes() и str_replace().

stripslashes() удаляет обратные слэши (\), которые добавляет WordPress, до того как вставляет запись в базу данных. Обычно, WordPress самостоятельно удаляет эти слэши, до того как вывести контент на экран, но поскольку наш фильтр инициализируется до того как данные будут отображены, эта функция обязательна.

str_replace() – ищет угловые скобки и заменяет их на символьные объекты.

$1 и $2 – это значения выражения, где $1 = (<pre.*?>) и $2 = (.*?).

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

return $content_text;

Теперь, нам нужно внедрить наш фильтр в WordPress, так, чтобы он срабатывал в определенное время. В нашем случае, мы внедрим фильтр, внутрь фильтра «the_content»:

add_filter('the_content','mish_code_filter', 1, 1);

Фильтр “the_content”, как нетрудно догадаться, используется для фильтрации записей, после того, как они получены из базы данных и до того, как они выведены на экран. Поэтому, в нашем случае, мы сообщаем вордпрессу, о том, что наш фильтр (mish_code_filter) нужно использовать совместно с фильтром “the_content”.

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

Установка Фильтра

Откройте ваш файл functions.php (расположен в папке с вашей темой), и вставьте туда следующий код:

<?php
function mish_code_filter($content_text) {
    $content_text = preg_replace('!(<pre.*?>)(.*?)</pre>!ise', " '$1' .  stripslashes( str_replace(array('<','>'),array('&lt;','&gt;'),'$2') )  . '</pre>' ", $content_text);
    return $content_text;
    }

add_filter('the_content','mish_code_filter', 1, 1);
?>

Фильтр для Комментариев

Наш фильтр также можно использовать для фильтрации html, в тексте комментариев, для этого понадобятся совсем небольшие изменения. Первое, что нам нужно сделать – это заменить фильтр «the_content», на фильтр «comment_text», который выполняет ту же функцию, только для текста комментариев.

Ну и второе, необязательное изменение – теги <pre> мы заменим на теги <code>, так как они чаще используются в тексте комментариев. В результате у нас получится вот такой фильтр:

function mish_code_filter($content_text) {
    $content_text = preg_replace('!(<code.*?>)(.*?)</code>!ise', " '$1' .  stripslashes( str_replace(array('<','>'),array('&lt;','&gt;'),'$2') )  . '</code>' ", $content_text);
    return $content_text;
    }

add_filter('comment_text','mish_code_filter', 1, 1);

Устанавливается он точно так же, как фильтр контента. Вот и все, можете проверить – наш фильтр работает.

Плагины с похожей функциональностью

Перевод статьи «Adding and Filtering Raw HTML in WordPress Posts«, автор Martin