Кириличні заголовки постів у MangoBlog

З переїздом на Mango у нас відразу виникла проблема: при створенні токенів (імен) для URL постів на базі заголовку видалялись кириличні символи. Це відбувалось тому, що блоґ намагався зробити безпечні посилання, а в таких знаходилося місце тільки літерам латинки, цифрам та дефісам.

Наприклад, спробувавши створити такий пост:

mango_tokens_1_preface

Ми отримували не дуже гарне посилання на цей пост:

mango_tokens_2_problem

Найбільш серйозною проблемою була втрата унікальності URL'ів, коли "Мій пост про MySQL" мав би майже таке саме посилання, що й "Пост не тільки про MySQL". Майже, бо блоґ додав би якесь випадкове число для запобігання співпадінь.

Почухавши потилицю, я вирішив виправити це діло. Півгодини копирсання в коді дали зрозуміти, що найбільш безболісним буде шлях транслітерації заголовку до його "чистки".

Пошуки привели мене до службової компоненти Utilities.cfc (див. /components/). Серед її методів знайшовся передбачуваний regex методу makeCleanString():

<cfset cleanedString = rereplace(cleanedString, "[^a-z0-9]", "-", "all") />
<cfset cleanedString = rereplace(cleanedString, "-{2,}", "-", "all") />
<cfset cleanedString = rereplace(cleanedString, "(^-|-$)", "", "all") />

Не хотілось особливо влізати в працюючий код, тому довелось зробити своєрідного костиля -- новий метод transLitString(), котрий підміняє підходящі літери кирилиці на англійські відповідники згідно простої мапи замін, що міститься в самому ж методі. Виклик його вставлено на початку makeCleanString()

        <!--- Code provided by Seb Duggan, thank you! --->
        <cfset var s = this.transLitString(lcase(arguments.stringToClean)) />
        <cfset var i = 0 />
        <cfset var c = "" />
        <cfset var cleanedString = "" />

Код самої компоненти:

<cffunction name="transLitString" output="false" hint="Transliterates Cyr string to Latin" access="public" returntype="string">
    <cfargument name="stringToTrans" type="string" required="true">

        <cfset var tranString = "" />
        <cfset var i = 0 />
        <cfset var c = "" />
        <cfset var transMap = StructNew() />

        <cfscript>

            transMap["а"] = "a";
            transMap["б"] = "b";
            transMap["в"] = "v";
            transMap["г"] = "g";
            transMap["ґ"] = "g";
            transMap["д"] = "d";
            transMap["е"] = "e";
            transMap["є"] = "ye";
            transMap["ж"] = "zh";
            transMap["з"] = "z";
            transMap["и"] = "y";
            transMap["й"] = "y";
            transMap["і"] = "i";
            transMap["ї"] = "yi";
            transMap["к"] = "k";
            transMap["л"] = "l";
            transMap["м"] = "m";
            transMap["н"] = "n";
            transMap["о"] = "o";
            transMap["п"] = "p";
            transMap["р"] = "r";
            transMap["с"] = "s";
            transMap["т"] = "t";
            transMap["у"] = "u";
            transMap["ф"] = "f";
            transMap["х"] = "h";
            transMap["ц"] = "ts";
            transMap["ч"] = "ch";
            transMap["ш"] = "sh";
            transMap["щ"] = "sch";
            transMap["э"] = "e";
            transMap["ь"] = "";
            transMap["ы"] = "y";
            transMap["ъ"] = "";
            transMap["ю"] = "yu";
            transMap["я"] = "ya";

        </cfscript>

        <cfloop from="1" to="#len(arguments.stringToTrans)#" index="i">
            <cfset c = mid(arguments.stringToTrans,i,1) />
            <cfif StructKeyExists(transMap, c)>
                <cfset tranString = tranString & transMap[c] />
            <cfelse>
                <cfset tranString = tranString & c />
            </cfif>
        </cfloop>

    <cfreturn tranString />
</cffunction>

 

Ось як виглядає наш пост після підміни компоненти:

mango_tokens_3_translit

mango_tokens_4_fixed

 

Важлива примітка. На деяких інсталяціях ColdFusion можуть виникнути проблеми з розпізнаванням символів через помилки в обробці UTF-8, для вирішення проблеми достатньо вставити на початку компоненти директиву:

<cfprocessingdirective pageencoding="utf-8">

 

Пишіть рідною мовою про ColdFusion на здоров'я :)

 

 

Автор: Сергій Галашин | Опубліковано: 17.05.2009 о 18:39 | Категорії: Unicode - Gotchas - Mango Blog -

Відгуки