Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> utf-8, HTML::Template и warning 
V
    Опции темы
AlexPet
Дата 12.8.2008, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 5.12.2007
Где: Брянск

Репутация: 1
Всего: 1



Добрый день!

Пытаюсь разобраться с utf-8 применительно к шаблонизатору HTML::Template
Итак, имеем: файл шаблона содержит символы в кодировке utf-8
1) Если вызывать $htmltmpl->output() без передачи в шаблон параметров (либо с передачей параметров, не содержащих утф8-символы), то отображается все как надо
2) Если же передавать параметры, содержащие символы в кодировке utf-8, то на выходе получаем:
а) кразобляки в тех местах, где в шаблоне юникод
б) нормальные символы там, где были переданы параметры юникодные

Пробовал всяческие комбинации с use open :utf8; binmode STDOUT, ":utf8"; utf8::*. Не получилось.
Нашел в интернете решение ( http://www.mail-archive.com/html-template-...t/msg02273.html ), которое сводится к следующему:
Код

use utf8;
my $html = HTML::Template->new(filename => "template.tmpl", filter => \&tmpl2utf8);
sub tmpl2utf8 {
    my $ref = shift;
    utf8::decode(${$ref});
}

(можно конечно открывать файл самому темплейта, и при открытии указывать '<:utf8', а затем передавать его через filehandle => $fh, но это совсем некрасиво)

Вопрос: можно ли как-то изящнее решить данную проблему?

P.S. Сам я только начал работать с UTF-8, могу упустить какое очевидное решение  smile  
P.P.S. А warning в названии - это при использовании Encode::decode_utf8 вместо utf8::decode получался smile

Это сообщение отредактировал(а) AlexPet - 12.8.2008, 12:44
PM MAIL ICQ Jabber   Вверх
Bulat
Дата 15.8.2008, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: 5
Всего: 57



AlexPet, ммм даж не знаю поможет или нет, но просто 
Код

use utf8;


не пробовали ?? smile


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
AlexPet
Дата 18.8.2008, 08:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 5.12.2007
Где: Брянск

Репутация: 1
Всего: 1



Конечно пробовал smile
без толку. Пока нашел два решения (либо подключать темплейт как файловый дескриптор с указанием utf8 на open, либо через фильтр к темплейту.. об этом я, впрочем, написал выше)


Это сообщение отредактировал(а) AlexPet - 18.8.2008, 08:41
PM MAIL ICQ Jabber   Вверх
Bulat
Дата 18.8.2008, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: 5
Всего: 57



Цитата(AlexPet @  12.8.2008,  12:41 Найти цитируемый пост)
2) Если же передавать параметры, содержащие символы в кодировке utf-8, то на выходе получаем:
а) кразобляки в тех местах, где в шаблоне юникод
б) нормальные символы там, где были переданы параметры юникодные


Не совсем понял, т.е. в теории кодировка одна и та же, что в шаблоне, что у передаваемых параметров - utf8, но отображается по разному??


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
ginnie
Дата 18.8.2008, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



Уважаемый AlexPet, есть еще пара вариантов:

1. Попробовать 
Код

use open IO  => ":encoding(utf8)";


2. Создать дочерний класс HTML::Template::Unicode, в котором переопределить функцию open():

Код

use subs qw(open);

sub open (*;$@) {
    my $pkg = caller();
    if(defined($_[0])) {
        use Symbol ();
        my $fh = Symbol::qualify($_[0], $pkg);
        no strict 'refs';
        if(@_ == 1) {
            return CORE::open($fh);
        } elsif(@_ == 2) {
            return CORE::open($fh, "<:encoding(UTF-8)", $_[1]);
        } else {
            return CORE::open($fh, $_[1], @_[2..$#_]);
        }
    } else {
        if(@_ == 1) {
            return CORE::open($_[0]);
        } elsif(@_ == 2) {
            return CORE::open($_[0], "<:encoding(UTF-8)", $_[1]);
        } else {
            return CORE::open($_[0], $_[1], @_[2..$#_]);
        }
    }
}



--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
AlexPet
Дата 19.8.2008, 08:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 5.12.2007
Где: Брянск

Репутация: 1
Всего: 1



Bulat, в теории да, но HTML::Template использует хитрый алгоритм (который описан по ссылке выше):
Цитата

If a parameter contains wide characters (katakana, or accented latin
characters for example), then the bytes from the templates are made to
match the wide characters by translating the bytes to Unicode.  This is
done by interpreting the bytes as Latin-1 characters.

If the template file happens to contain Unicode already, this breaks:
the bytes making up an UTF-8 character are fed to the Latin => unicode
transformation, and you end up with characters that are encoded twice.



ginnie, по этой же причине не будет работать и первый предложенный Вами метод (поскольку модуль сам осуществляет перекодировки, и не всегда правильно). За второй метод спасибо, возьму на заметку, если нужно будет использовать в серьезном проекте. Пока что быстро слабал на коленке через фильтр smile

Очень странно, что до сих пор не закоммитили предложенное изменение в этот модуль. Все-таки проблема известная, и патч был предложен для ее решения (опять же по ссылке в моем первом посте)...

Всем спасибо за обсуждение, тему помечаю как решенную (будем ждать новых релизов хтмл::темплейт ;) )
PM MAIL ICQ Jabber   Вверх
Ramirez
Дата 20.8.2008, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 305
Регистрация: 18.1.2005
Где: Moscow, ExUSSR

Репутация: 4
Всего: 5



Я так понимаю, если шаблон берется не из файла (из базы например) то этой проблемы не возникает?
PM ICQ   Вверх
AlexPet
Дата 20.8.2008, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 5.12.2007
Где: Брянск

Репутация: 1
Всего: 1



Не совсем понял, что значит из базы (шаблон можно брать либо из файла, либо из файлового манипулятора), но решение в случае с файловым манипулятором я привел выше (через указание кодировки на поток)
PM MAIL ICQ Jabber   Вверх
Ramirez
Дата 22.8.2008, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 305
Регистрация: 18.1.2005
Где: Moscow, ExUSSR

Репутация: 4
Всего: 5



Ну вот собственно как-то так:

Код

  my $t = HTML::Template->new( scalarref => $ref_to_template_text, 
                               option => 'value' 
                             );

  my $t = HTML::Template->new( arrayref => $ref_to_array_of_lines , 
                               option => 'value' 
                             );


где переменная $ref_to_template_text или $ref_to_array_of_lines содержит текст шаблона. А браться он может откуда угодно. Хоть динамически генерироваться. 

Это сообщение отредактировал(а) Ramirez - 22.8.2008, 11:39
PM ICQ   Вверх
Vavilen
Дата 4.3.2012, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 18.1.2009

Репутация: нет
Всего: нет



Цитата(AlexPet @  12.8.2008,  12:41 Найти цитируемый пост)
Нашел в интернете решение ( http://www.mail-archive.com/html-template-...t/msg02273.html ), которое сводится к следующему:

Код

use utf8;
my $html = HTML::Template->new(filename => "template.tmpl", filter => \&tmpl2utf8);
sub tmpl2utf8 {
    my $ref = shift;
    utf8::decode(${$ref});
}

(можно конечно открывать файл самому темплейта, и при открытии указывать '<:utf8', а затем передавать его через filehandle => $fh, но это совсем некрасиво)

Вопрос: можно ли как-то изящнее решить данную проблему?


Мне очень помогло Ваше решение! Спасибо!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0718 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.