2010-07-26 39 views
13

tôi liên tục nhận được lỗi này bằng mako:làm thế nào để đối phó với unicode trong mako?

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

Tôi đã nói với mako Tôi đang sử dụng unicode trong bất kỳ cách nào có thể:

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) 

Tất cả các file mẫu của tôi bắt đầu với:

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

và bên trong chúng, tất cả các chuỗi chi phí đều có tiền tố là "u". Tôi biết tham số self.stuff có chứa các chuỗi unicode, nhưng cách tôi khởi tạo các đối tượng mako sẽ quan tâm đến nó (nếu không thì những đối số đó là gì tốt?). Có điều gì tôi quên làm không?

Một câu hỏi nữa: điểm của encoding_errors = 'replace' là gì?

= EDIT = tôi rời chỉ là một chuỗi unicode đơn và đây là 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

này là tốt đẹp: tôi đã thoát khỏi mã để lại một $ đơn {unicode_string_value.decode tất cả các mẫu của tôi ('utf-8')} và đoán cái gì? mako vẫn tăng ngoại lệ ... –

+0

xin vui lòng hiển thị các traceback –

+0

oh và tôi quên đề cập đến rằng nếu tôi chạy/gỡ lỗi ứng dụng bên trong Eclipse + PyDev, mako không báo cáo bất kỳ lỗi nào và kết quả html là ok. khởi chạy từ bảng điều khiển hoặc lối tắt dẫn đến lỗi unicode. –

Trả lời

13

Cuối cùng tôi lưu mẫu của tôi trong unicode, trên thực tế (tôi đoán) utf-16 thay vì utf-8. kích thước của chúng trên đĩa tăng lên gấp đôi và mako bắt đầu phàn nàn về một "CompileException (" hoạt động giải mã Unicode mã hóa 'utf-8' bla bla", vì vậy tôi đã thay đổi dòng đầu tiên trong tất cả trong số họ trong:

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

loại bỏ tất cả các ".decode ('utf-8')" - các hằng xâu vẫn bắt đầu bằng "u"

các khởi tạo trong python bây giờ là:

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') 

nó hoạt động bây giờ trông như thế nào.. utf-8 là lựa chọn sai (hoặc tôi không có khả năng lưu templ ates trong utf-8), nhưng tôi không thể giải thích lý do tại sao nó hoạt động từ eclipse/pydev.

1

Vì lợi ích nhân viên của Google:

Mako đặt ra một ngoại lệ mako.exceptions.CompileException: Unicode decode operation of encoding 'ascii' failed in file, vv, khi tập tin mẫu của bạn am hiểu về các ký tự không ascii, và khi BOM Unicode không được viết vào tập tin. Bạn cần phải tự thêm các BOM (điều này không được thực hiện tự động, ít nhất là trong trình soạn thảo văn bản của tôi), do đó này:

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

trở này:

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

Điều này không còn đúng nữa. Nếu tệp là utf-8 không có BOM và input_encoding là 'utf-8', thì ít nhất nó sẽ hoạt động với Mẫu, không thử TemplateLookup. – Javier

0

Không ai trong số các đề xuất này (bao gồm cả câu trả lời được chấp nhận) hoạt động trong mọi trường hợp, cụ thể là nơi mẫu mako hiển thị nội dung (ví dụ: $ {value | n}) trong đó giá trị chứa các ký tự không phải ascii.

Đây là vì theo mặc định mako kết thúc tốt đẹp unicode (foo) xung quanh bất kỳ giá trị trong các mẫu thu thập được tạo ra, mà vẫn sẽ cho kết quả:

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

duy nhất chắc chắn cách chữa cháy làm mako xử lý unicode trong python2 là để thay thế mặc định ('unicode') xử lý, như thế này:

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) 
Các vấn đề liên quan