Сегодня у Lecacus'а на сайте наткнулся на упоминание одной нерешённой проблемы:

У меня не работают автоматические ссылки меток в содержимом записи для меток на русском языке. Т.е. если есть метка "wordpress", то слово "wordpress" заменяется на ссылку http://myblog.net/tag/wordpress/. А вот если есть метка "спорт", то слово "спорт" ссылкой не заменяется. Подскажите как сделать так, чтобы плагин работал и с русскими метками.

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

Сам по себе код плагина довольно-таки простой (что определённо делает честь автору), но регулярные выражения, использованные в коде, требуют некоторых знаний и навыков.

За создание автоматических меток отвечает метод SimpleTags::autoLinkTags, основу которого составляют регулярные выражения из PHP Markdown Михеля Фортина (Michel Fortin); замечу, что эти регулярные выражения исправлять не пришлось (хотя, по-хорошему, их можно упростить).

Сама ошибка находится в данной строке:

[-]
View Code PHP
  1. $match = "/\b" . preg_quote($term_name, "/") . "\b/".$case;

Очень многие "Забугорные" программисты (а также наши, работающие на иностранцев), привыкли считать, что нет иной кодовой таблицы, нежели iso-8859-x, что, собственно, и выражается в регулярном выражении.

Те, кто знаком с PCRE, знают, что \b — это граница слова. Но в локали по умолчанию русские буквы не попадают в категорию "буквы"; как следствие, регулярное выражение /\bспорт\b/ не сработает.

Решение проблемы состоит в использовании классов символов Unicode (то, что знают, увы, очень немногие программисты).

Фактически, нужно было проверять на нахождение не-буквы перед меткой и после метки; например, так:

[-]
View Code PHP
$match = "/(\PL)(" . preg_quote($term_name, "/") . ")(\PL)/u".$case;

Уже лучше, но работает не всегда. В частности, не будет работать, если метка идет сразу после открывающего тэга, либо сразу перед закрывающим тэгом (не сработает условие (\PL) в начале или в конце). Правильным решением будет следующее:

[-]
View Code PHP
$match = "/(\PL|\A)(" . preg_quote($term_name, "/") . ")(\PL|\Z)/u".$case;

Полное решение выглядит сложнее, но суть должна быть понятна.

Ниже приведён патч в формате unified diff:

--- simple-tags.client.php.orig 2008-11-22 06:15:22.000000000 +0200
+++ simple-tags.client.php      2008-11-22 07:53:15.000000000 +0200
@@ -262,8 +262,9 @@
 
                        foreach ( (array) $this->link_tags as $term_name => $term_link ) {
                                $filtered = ""; // will filter text token by token
-                               $match = "/\b" . preg_quote($term_name, "/") . "\b/".$case;
-                               $substitute = '<a href="'.$term_link.'" class="st_tag internal_tag" '.$rel.' title="'. attribute_escape( sprintf( __('Posts tagged with %s', 'simpletags'), $term_name ) )."\">
+                               $quoted = preg_quote($term_name, "/");
+                               $match = "/(\PL|\A)(" . preg_quote($term_name, "/") . ")(\PL|\Z)/u".$case;
+                               $substitute = '$1<a href="'.$term_link.'" class="st_tag internal_tag" '.$rel.' title="'. attribute_escape( sprintf( __('Posts tagged with %s', 'simpletags'), $term_name ) )."\
 
                                // for efficiency only tokenize if forced to do so
                                if ( $must_tokenize ) {

Внимание: патч будет работать только если PHP собран с поддержкой UTF-8, если кодировка блога установлена в UTF-8 и соединение с базой данных тоже использует кодировку UTF-8. В принципе, ничего запредельного, нормальная инсталляция WordPress будет отвечать этим требованиям.

Те, кто не хотят заморачиваться с патчем, могут скачать пропатченную версию (но она требует как минимум WordPress 2.5).

Скачать Simple Tags 1.5.7.1.

Добавить в закладки
  • del.ici.ous
  • Digg
  • Furl
  • Google
  • Simpy
  • Spurl
  • Y! MyWeb
  • БобрДобр
  • Мистер Вонг
  • Яндекс.Закладки
  • Текст 2.0
  • News2
  • AddScoop
  • RuSpace
  • RUmarkz
  • Memori
  • Закладки Google
  • Писали
  • СМИ 2
  • Моё Место
  • Сто Закладок
  • Ваау!
  • Technorati
  • RuCity
  • LinkStore
  • NewsLand
  • Lopas
  • Закладки - I.UA
  • Connotea
  • Bibsonomy
  • Trucking Bookmarks
  • Communizm
  • UCA

Связанные записи

22
Ноя
2008

Комментарии к статье «Simple Tags и автоматические ссылки меток на русском языке» (11)  »

  1. Михаил says:

    Здравствуйте Владимир.
    Написал на блоге Кактуса благодарность в вашу сторону и решил повторить здесь.
    После установки пропатченного плагина сразу пошла линковка ru тегов, что и требовалось доказать.
    Огромное спасибо за испраление бага. Очень хотелось подключить эту функцию.
    Благодаря вам я реализовал это на своем сайте.
    Еще раз СПАСИБО!
    Михаил.

  2. Vladimir says:

    Михаил, всегда пожалуйста! :-)

    Будут вопросы — обращайтесь!

  3. Lex Nevermind says:

    Огромное спасибо. Тоже долго с плагином мучался, пока блог Кактуса не почитал и сюда не попал.

  4. Сергей Жуковский says:

    у меня выдает

    Warning: preg_match() [function.preg-match]: Compilation failed: PCRE does not support \L, \l, \N, \P, \p, \U, \u, or \X at offset 2 in /home/codeby/www/wp-content/plugins/simple-tags/2.5/simple-tags.client.php on line 288

    • Vladimir says:

      Какая версия PHP?

      • Сергей Жуковский says:

        PHP Version 5.2.4

        • Vladimir says:

          Red Hat Linux, я полагаю?

          Что говорит phpinfo() по поводу версии PCRE?

          Если есть shell, можно посмотреть так:

          [-]
          View Code Bash
          php -i | grep "PCRE Library Version"

          Полагаю, что версия будет меньше пятой (например, 4.5)?

          • Сергей Жуковский says:

            PCRE Library Version 4.5 01-December-2003

          • Vladimir says:

            Значит, я был прав… Увы, программно здесь ничего нельзя сделать: сборщик пакета PHP для Вашей операционной системы сделал непростительную тупость: он собрал новую версию PHP со старой библиотекой PCRE (самая последняя версия PCRE — 7.8 от 5 сентября 2008 года).

            Если у Вас выделенный сервер, могу посоветовать только пересобрать PHP по-нормальному.

            PS — поддержка Unicode добавлена в PCRE только в пятой версии.

  5. Lecactus says:

    вышла новая версия 1.6.1 с новыми улучшениями и исправлениями (для версии 2.7 пофиксили некоторые места).
    в приведенном потче в последней “зеленой строке” в конце обрезано. это так к слову. просто решил новую версию исправить по методике и когда патчил заметил что тут недописана строка (несколько символов затерялось). исправил у себя сам и выложил обновленный архив плагина тут http://lecactus.ru/2007/10/07/851/

Подписаться на RSS-ленту комментариев к статье «Simple Tags и автоматические ссылки меток на русском языке» Trackback URL: http://blog.sjinks.org.ua/wordpress/patches/372-simple-tags-auto-link-tags-in-russian/trackback/

Оставить комментарий к статье «Simple Tags и автоматические ссылки меток на русском языке»

Вы можете использовать данные тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, Вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя