Как правильно экранировать вывод (для XHTML) в мако? - PullRequest
3 голосов
/ 24 января 2010

Несмотря на то, что предлагая хороший способ избежать вывода с помощью фильтров, ни один из них не делает правильных действий. Взяв строку:

x=u"&\u0092"

Фильтры выполняют следующее:

x             Turns the & into an entity but not the \u0092 (valid XML but not XHTML)
h             Exactly the same
u             Escapes both, but obviously uses url escaping
entities      Only converts named entities, so again only the & is escaped
decode.latin1 The same

HTML использует стандартный репертуар символов Консорциума UNICODE и оставляет неопределенными (среди прочих) 65 кодов символов (от 0 до 31 включительно и от 127 до 159 включительно)

Кажется, это пропущенные персонажи. Есть идеи?

EDIT

Кажется, для проверки, если я использую файл в автономном режиме. Может ли это быть проблемой типа контента?

Ответы [ 2 ]

2 голосов
/ 24 января 2010

Нет необходимости преобразовывать символы Юникода в форму &#xxxx; для работы в HTML, если только вы не намеренно используете кодировку ASCII. Проще и эффективнее избежать именованных сущностей, затем кодировать всю строку в UTF-8 и записывать ее таким образом. Вам, вероятно, следует объявить кодировку, используемую в заголовках HTTP или в теге <meta>.

EDIT:

Кажется, для проверки, если я использую файл в автономном режиме. Может ли это быть проблемой типа контента?

Да. Вы можете использовать HTTP-заголовки для применения кодировки UTF-8 или указать ее в HTML-коде непосредственно через метатег:

<meta http-equiv="Content-Type" content="application/xhtml+xml;charset=utf-8" />
1 голос
/ 24 января 2010

За исключением вопросов проверки, полезно иметь возможность удалять эти символы (которые все равно не отображаются надежно) без , обязательно избегая чего-либо еще Для этого я добавил следующую функцию в lib / helpers.py:

__sgml_invalid = re.compile(r'[\x82-\x8c\x91-\x9c\x9f]', re.UNICODE)

def sgmlsafe(text):
    lookup = {
        130:"&#8218;",    #Single Low-9 Quotation Mark
        131: "&#402;",    #Latin Small Letter F With Hook
        132:"&#8222;",    #Double Low-9 Quotation Mark
        133:"&#8230;",    #Horizontal Ellipsis
        134:"&#8224;",    #Dagger
        135:"&#8225;",    #Double Dagger
        136: "&#710;",    #Modifier Letter Circumflex Accent
        137:"&#8240;",    #Per Mille Sign
        138: "&#352;",    #Latin Capital Letter S With Caron
        139:"&#8249;",    #Single Left-Pointing Angle Quotation Mark
        140: "&#338;",    #Latin Capital Ligature OE
        145:"&#8216;",    #Left Single Quotation Mark
        146:"&#8217;",    #Right Single Quotation Mark
        147:"&#8220;",    #Left Double Quotation Mark
        148:"&#8221;",    #Right Double Quotation Mark
        149:"&#8226;",    #Bullet
        150:"&#8211;",    #En Dash
        151:"&#8212;",    #Em Dash
        152: "&#732;",    #Small Tilde
        153:"&#8482;",    #Trade Mark Sign
        154: "&#353;",    #Latin Small Letter S With Caron
        155:"&#8250;",    #Single Right-Pointing Angle Quotation Mark
        156: "&#339;",    #Latin Small Ligature OE
        159: "&#376;"     #Latin Capital Letter Y With Diaeresis
        }

    return __sgml_invalid.sub(lambda x: lookup[ord(x.group())], text)

И вы можете сделать это доступным в качестве фильтра, отредактировав environment.py:

config['pylons.app_globals'].mako_lookup = TemplateLookup(
    ...
    imports=[....,'from appname.lib.helpers import sgmlsafe',...]

Затем он должен быть доступен для ваших шаблонов:

${c.content|n,sgmlsafe}
...