
Небольшое отступление... Череда байтов "EF BB BF", именуемая меткой порядка байтов (byte order mark, BOM), применяется для обозначения формата UTF-8, хотя к этому формату и неприменимо понятие порядка байтов.
Поиск решений
Поискав решение проблемы наткнулся на пару топиков:- Template adds extra characters when using utf8 file encoding.
"The first bytes of your header.html file are EF BB BF. That's the UTF-8 encoding of the BOM...It proposes noting, stripping, and relocating the BOM to the front of the ultimately rendered template."
- Django Templates and BOM (byte order marks).
"If I will render page.html output will contain TWO byte order marks:
!UTF_8_BOM!!UTF8_BOM!<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN" ... "
- weird problem with django templates.
"...when templates are being rendered (i guess), in code, right before the doctype, strange character is being placed. I call it "strange" because if I select it, copy it and try to paste nothing is pasted. This "dot" is seen only if I do "view source" in webkit browsers..."
Все решения сводятся к одному - сохраняйте файлы шаблонов в формате UTF-8 без BOM! :) А что делать, если редактор не позволяет сохранять файлы в кодировке UTF-8 без BOM?
Тут есть несколько решений:
1. Запустить скрипт, который удалит все BOM символы в шаблонах.
2. Использовать обработку шаблонов при загрузке.
Например, в качестве IDE я использую Eclipse и кодировку UTF-8 для файлов. Ну и вот этот "паршивец" считает своим долгом поместить в каждый файл шаблона BOM байты (поиск решение по отключению этого эффекта не дал результата). А каждый раз запускать скрипт не удобно, так что выбираем второе решение.
Обработка шаблонов для удаления BOM символов при загрузке
Смотрим какие загрузчики нужно поправить (settings.py):
TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.load_template_source', 'django.template.loaders.app_directories.load_template_source',
)
Писать наследников "лень", так что используем monkey patching. Пишем небольшую корректирующую функцию :), помещаем ее и инициализацию в файл urls.py.
def patch_load_template_source(func):
def decorator(self, template_name, template_dirs=None):
item = func(self, template_name, template_dirs)
//для сравнения, по хорошему, bom байты нужно переводить в ту же кодировку, что и кодировка загруженного файла. опустил этот момент.
if item[0][:1]==u'\ufeff':
return (item[0][1:], item[1])
return item
return decorator
//патчим filesystem.Loader
from django.template.loaders import filesystem
filesystem.Loader.load_template_source = patch_load_template_source(filesystem.Loader.load_template_source)
//патчим app_directories.Loader
from django.template.loaders import app_directories
app_directories.Loader.load_template_source = patch_load_template_source(app_directories.Loader.load_template_source)
ЗЫ: Данный пример не претендует на звание идеального, а лишь демонстрирует рабочую версию одного из решений :).
0 коммент.:
Отправить комментарий