LINUX.ORG.RU

python unicode mako


0

0

Привет,

решил попробовать написать программку для гуглева app engine. Сначала начал с django темплейтным движком. Все нормально. Текст по русски ввожу, все сохраняется в базе и потом django рендерит текст и не жужжит. А потом решил перелезть на mako, так как оно удобнее для меня, да и привык я. Проблема с mako одна, не хотит показывать нормально текста на русском. Проблема возникает, как я понял, с классами в которых свой кастомный __str__() метод реализован.

Если просто напишу в темплейте ${ctx.user} где user просто строка в unicode. То получаю ошибку, что кодек ascii не может сконвертировать символ с кодом более 0127. Я добавил свой фильтр, который применяется ко всем текстам автоматом

def enc(input): return input.encode( "utf-8" )

С простыми текстами все заработало. Русский текст показывает отлично. Но вот если ctx.user это класс, то мой фильтр обламывается конечно, потому как метода encode у него нету. Пробовал так

def enc(input): return str(input).encode( "utf-8" )

получаю опять же ошибку про ascii кодек

Если же в темплейте напишу ${str(ctx.user)} то все срабатывает. Но это же геммор везде заворачивать переменные в str().

Читал доку mako. что касается unicode, но так ничего не понял. Может мне объясните, как бороться с unicode в питоне/mako? Почему в django таких проблем нету?

Спасибо

> в которых свой кастомный __str__() метод реализован

А надо кастомный __unicode__ и чтоб движок умет полученный unicode правильно отображать: кодировать либо в utf-8, либо в то, что в конфиге указано. Если он так не умеет, значит нельзя ему подсовывать unicode, надо самому переводить в str.

Если я правильно понял, надо сделать
def enc(input): return unicode(input).encode( "utf-8" )
и в классах, к которым input может относиться, реализовывать __unicode__().

const86 ★★★★★
()

У меня такой лукап:

lookup = TemplateLookup(
    # tpl and tmp directories skipped
    input_encoding='utf-8',
    output_encoding='utf-8',
    default_filters=['myunicode'],
    # default imports skipped
)

Фильтр, через который проходят все строки и объекты:

def myunicode(data):
    if hasattr(data, '__unicode__'): data = data.__unicode__()
    if isinstance(data, unicode): return data
    if not isinstance(data, str): data = str(data)
    return unicode(data, 'utf-8')

Причем в джанго уже есть подобная функция. Непомню где определена и как называется.

Такой способ позволяет работать с объектами, у которых не опреден __unicode__

baverman ★★★
()
Ответ на: комментарий от baverman

Классно, спасибо, так и зделаю. Примерно до этого же дошел. Еще рендер вызывается не просто render, а render_unicode().encode("utf-8") и сразу все успокоилось.

the_moon
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.