Вставка кода в комментариях

C самого начала работы этого блога я предусмотрел возможность вставлять в записи и комментарии код с помощью плагина WP-Syntax. Даже специально перед формой добавления комментария написал подсказку, как правильно использовать синтаксис вставки кода. Именно поэтому меня страшно раздражало, когда посетители вставляли код так, что половина его съедалась и я не мог понять о чем идет речь и как помочь комментирующему. Продолжалось это ровно до того момента, пока я не попытался сам ответить с кодом в комментарии, будучи не авторизован в блоге. К моему большому удивлению часть моего кода в комментарии оказалась испорченной. Как пример: вот из такого простого кода в комментарии:

Я получил почему-то обрезок в виде:

Все div'ы оказались вырезанными из комментария, даже несмотря на то, что их защищали теги pre (с тегами code тоже самое, кстати).

Я стал разбираться в ситуации и довольно быстро нашел проблему. Оказывается, что нефильтрованный HTML-код разрешено вставлять в блоге только его администратору. Естественно, что давать возможность вставки любого HTML-кода обычным посетителям очень плохая идея, но меня убило, что код нельзя вставлять даже в специальных тегах code, которые, собственно, и предназначены именно для вставки кода. WordPress'у по барабану вставлен код в тегах code или нет, он все равно фильтрует весь комментарий. Причем, что интересно – сами теги code он не фильтрует, не считая их опасными, но вот их содержимое зачем-то портит, хотя чем оно может навредить блогу, находясь в ограничивающих тегах?

Анализ кода движка показал, что WordPress фильтрует HTML-теги в момент добавления комментария, а поэтому дело свелось к следующему: не дать WordPress'у удалить HTML-код, заключенный в теги code. Это уже оказалось задачей достаточно простой – надо заставить WordPress не воспринимать HTML-код, как код. А для этого надо всего лишь заменить все атрибуты тегов в виде < и > на их escape-последовательности &lt; и &gt;. Не буду вас дальше утомлять: вот готовый хак для тегов code и pre, его достаточно добавить в файл functions.php вашего шаблона:

function replace_code_pre ($matches){
    $out = str_replace( array('<','>'), array('&lt;','&gt;'), $matches[3] );
    return "<{$matches[1]}{$matches[2]}>".$out."</{$MATCHES[1]}>";
}
function code_in_comments($comment_text){
    $comment_text = preg_replace_callback ('!<(pre|code)([^>]*)>(.*?)</\\1>!ims', 'replace_code_pre', $comment_text);
    return $comment_text;
}
add_filter ('pre_comment_content','code_in_comments');

Теперь при добавлении комментария:

Вы увидите именно код, а не обрезок:

Для плагина WP-Syntax и его тегов pre аналогично - из комментария:

можно получить на этот раз правильный код:

Причем остальная часть комментария данными фильтрами не трогается и весь HTML-код вне тегов code или pre будет удален, если автор комментария не имеет прав добавления нефильтрованного HTML-кода в блоге. Надеюсь, данный способ кому-нибудь пригодится.

PS. Огромное спасибо Тимуру Камаеву, автору сайта WP-Kama.ru, за предоставление более правильного и корректного кода.

Понравился пост? Подпишись на обновления по Обновления блога по RSSRSS или Обновления блога на TwitterTwitter !

Комментарии (всего 19 комментариев)
Написать комментарий

(обязательно)

(обязательно, не публикуется)

Для вставки кода используйте кнопку "Код", по умолчанию используется синтаксис подсветки языка "php", вы можете поменять его на любой другой поддерживаемый GeSHi язык, например "javascript", "css", "html4strict", "sql" и тд. Используйте предпросмотр!
 


Подписаться на уведомления без комментирования.