SLY_G
@SLY_G
журналист, переводчик, программист, стартапщик

Template::Toolkit и utf-8 в шаблонах

Следующая проблема не даёт спать.

perl, v5.10.1 built for MSWin32-x86-multi-thread (acivestate)
template::toolkit 2.22

В скриптах везде указано use utf8, во всех скриптах и во всех темплейтах есть BOM-заголовок, все сохранены в utf.
Инициализация так сделана:
$tt = Template->new({
INCLUDE_PATH => $$cfg{tpl_path},
ENCODING => 'utf8',
}) || die "$tt::ERROR\n";

Проблема:
если в шаблоне есть не-ascii символ, к примеру, любая русская буква — тогда на выходе получается каша вида "Глупый вопрос" (при этом русские буквы, которые в шаблоне присутствовали, читаются).

Если в шаблоне только ascii, тогда всё работает нормально, включая русские строки, которые изымаются из базы и вставляются в шаблоны.
То есть, TT не хочет нормально работать с шаблонами, в которых изначально есть русские буквы. При этом строит страницы по этим шаблонам без проблем, даже если в значениях переменных оказываются русские буквы.
Ставил в вызовах process() опцию binmode => ':utf8', не помогает.

Как-то это лечится?
  • Вопрос задан
  • 3373 просмотра
Пригласить эксперта
Ответы на вопрос 3
SLY_G
@SLY_G Автор вопроса
журналист, переводчик, программист, стартапщик
Всем спасибо за помощь.

Проблема решается единственной директивой:

$dbh -> {'mysql_enable_utf8'} = 1;

По-умолчанию стоит «0», поэтому, я подозреваю, TT конвертил данные от sql в utf самостоятельно, но как-то не в том месте, в результате какие-то данные оказывались дважды преобразованными в utf.
Ответ написан
Комментировать
SLY_G
@SLY_G Автор вопроса
журналист, переводчик, программист, стартапщик
Похоже, проблема всё-таки не в TT.

Такой вот скрипт:

use utf8;
use open OUT => ':utf8';
use DBI;
my $dbh = DBI->connect(«DBI:mysql:database=mybase;host=localhost;port=3306», «login», «pass»);
#$dbh->do('SET CHARACTER SET utf8');

open TST, '>utftest1.txt';
binmode TST;
print TST «русский»;

$test = $dbh->selectrow_array(«SELECT 'русский'»);
open TST, '>utftest2.txt';
binmode TST;
print TST $test;

Файл utftest1.txt содержит 14 байт, и если его смотреть любым текстовым редактором, видно слово «русский».
Файл utftest2.txt содержит 28 байт непонятно чего (двойная перекодировка?):

0000000000: C3 91 C2 80 C3 91 C2 83 │ C3 91 C2 81 C3 91 C2 81
0000000010: C3 90 C2 BA C3 90 C2 B8 │ C3 90 C2 B9

Но при этом то, что выдаёт DBI, обрабатывается при помощи TT правильно в моих скриптах! А проблемы начинаются, если в скрипт или шаблон вставлять русские символы.
Ответ написан
Комментировать
SLY_G
@SLY_G Автор вопроса
журналист, переводчик, программист, стартапщик
Удалось сделать небольшой скрипт, где возникает ошибка.

файл со скриптом:

use utf8;
use strict;
use vars qw($dbh $tt);
use DBI;
use Template;

$dbh = DBI->connect(«DBI:mysql:database=mybase;host=localhost;port=3306», «login», «pass»);

$tt = Template->new({
INCLUDE_PATH => '.',
DEFAULT_ENCODING => 'utf8',
ENCODING => 'utf8',
}) || die "$tt::ERROR\n";

my $testvar = $dbh->selectrow_array(«SELECT 'Текст'»);

$tt->process('template.htm', { 'testvar' => $testvar }) || die $tt->error(), "\n";

Темплейт — в отдельном файле template.htm

Если в темплейте оставить следующее:
[% testvar %] and some ascii text.

тогда отрабатывает ок, на выходе получаем «Текст and some ascii text.»

Если в темплейт добавить русский текст, например
[% testvar %] русский and some ascii text.

то на выходе имеем кашу:
Текст русский and some ascii text.

При этом оба файла, и скрипт и темплейт, сохранены в utf-8 с заголовком BOM.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы