2010-07-26 40 views
13

ja ciągle ten błąd przy użyciu mako:jak radzić sobie z unicode w mako?

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 6: ordinal not in range(128) 

Mówiłem mako używam unicode w każdy możliwy sposób:

mylookup = TemplateLookup(
     directories=['plugins/stl/templates'], 
     input_encoding='utf-8', 
     output_encoding='utf-8', 
     default_filters=['decode.utf8'], 
     encoding_errors='replace') 

    self.template = Template(self.getTemplate(), lookup=mylookup, 
     module_directory=tempfile.gettempdir(), 
     input_encoding='utf-8', 
     output_encoding='utf-8', 
     default_filters=['decode.utf8'], 
     encoding_errors='replace') 

    html = self.template.render_unicode(data=self.stuff) 

Wszystkie moje pliki szablonów rozpoczyna się:

## -*- coding: utf-8 -*- 

i wewnątrz nich wszystkie ciągi znaków są poprzedzone "u". Wiem, że parametr self.stuff zawiera ciągi znaków Unicode, ale sposób, w jaki uruchamiam obiekty mako powinien się nim zająć (w przeciwnym razie, do czego te argumenty są przydatne?). Czy jest coś, o czym zapomniałem?

Jeszcze jedno pytanie: jaki jest sens encoding_errors = 'replace'?

= EDIT = Wyszedłem tylko jeden ciąg Unicode i jest to traceback:

Traceback (most recent call last): 
    File "C:\My Dropbox\src\flucso\src\plugins\stl\main.py", line 240, in updateView 
    flags=self.makoflags) 
    File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\template.py", line 198, in render_unicode 
    as_unicode=True) 
    File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\runtime.py", line 403, in _render 
    _render_context(template, callable_, context, *args, **_kwargs_for_callable(callable_, data)) 
    File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\runtime.py", line 434, in _render_context 
    _exec_template(inherit, lclcontext, args=args, kwargs=kwargs) 
    File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\runtime.py", line 457, in _exec_template 
    callable_(context, *args, **kwargs) 
    File "memory:0x41317f0", line 89, in render_body 
    File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\runtime.py", line 278, in <lambda> 
    return lambda *args, **kwargs:callable_(self.context, *args, **kwargs) 
    File "FriendFeed_mako", line 49, in render_inlist_entry 
    File "C:\Python26\lib\encodings\utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u263c' in position 8: ordinal not in range(128) 
+0

to jest ładne: pozbyłem kod pozostawiając pojedynczy $ {unicode_string_value.decode wszystkich moich szablonów ('utf-8')} i , Zgadnij co? mako wciąż podnoszą wyjątek ... –

+0

proszę o przedstawienie traceback –

+0

oh i zapomniałem wspomnieć, że jeśli uruchomię/debuguję aplikację wewnątrz Eclipse + PyDev, mako nie zgłasza żadnego błędu i wynikowy HTML jest w porządku. uruchomienie z konsoli lub skrótu skutkuje błędem Unicode. –

Odpowiedz

13

końcu uratowałem moje szablony w Unicode, faktycznie (chyba) UTF-16 zamiast UTF-8. ich rozmiar na dysku dwukrotnie i mako zaczął narzekać na „CompileException (” Unicode operacji dekodowania kodowania UTF-8 'bla bla”, więc zmieniłem pierwszy wiersz w każdym z nich:

## -*- coding: utf-16 -*- 

i usunięte wszystkie ".decode ('utf-8')" - stałe ciągi są nadal poprzedzone "u"

te pliki uruchamiania w Pythonie teraz to:

mylookup = TemplateLookup(
    directories=['plugins/stl/templates'], 
    input_encoding='utf-16', 
    output_encoding='utf-16', 
    encoding_errors='replace') 

self.template = Template(self.getTemplate(), lookup=mylookup, 
    module_directory=tempfile.gettempdir(), 
    input_encoding='utf-16', 
    output_encoding='utf-16', 
    encoding_errors='replace') 

działa teraz wygląda.. utf-8 był złym wyborem (lub moją niezdolnością do uratowania templ ates w utf-8), ale nie potrafię wyjaśnić, dlaczego działa z eclipse/pydev.

1

Dla Googlersami:

Mako podnosi wyjątek mako.exceptions.CompileException: Unicode decode operation of encoding 'ascii' failed in file, etc., gdy plik szablonu pojmuje znaków spoza ASCII, a gdy BOM Unicode nie jest zapisywana w pliku. Trzeba ręcznie dodać BOM (nie odbywa się automatycznie, przynajmniej w moim edytorze tekstu), tak, że w ten sposób:

$file test.htm 
test.htm: HTML document, UTF-8 Unicode text 

staje się w ten sposób:

$file test.htm 
test.htm: HTML document, UTF-8 Unicode (with BOM) text 
+1

To już nie jest prawda. Jeśli plik jest utf-8 bez LM, a input_encoding to 'utf-8', to przynajmniej będzie działał z Template, nie próbował TemplateLookup. – Javier

0

Żadna z tych propozycji (w tym zaakceptowana odpowiedź) działa we wszystkich przypadkach, szczególnie tam, gdzie szablon mako renderuje zawartość (np. $ {wartość | n}), gdzie wartość zawiera znaki inne niż ASCII.

To dlatego, że domyślnie mako owija Unicode (foo) wokół żadnej wartości w wygenerowanym opracowanych szablonów, które wciąż spowoduje:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 0: ordinal not in range(128) 

Jedyny pewny sposób ogień dokonywania ostronos uchwyt unicode w python2 jest zastąpić domyślne ('unicode') obsługi, na przykład:

def handle_unicode(value): 
    if isinstance(value, basestring): 
     return unicode(value.decode('ascii', errors='ignore')) 
    return unicode(value) 


...  

lookup = TemplateLookup(
    directories=[self._root.template_path], 
    imports=['from utils.view import handle_unicode'], 
    default_filters=["handle_unicode"] 
) 

... 

template = self._lookup.get_template(self.template()) 
rtn = template.render(request=self.request) 
Powiązane problemy