В этой статье я хотел бы обсудить такую вещь, как текстовки в шаблонах. Казалось бы — есть это, и работает более-менее неплохо. Но все же имеется некоторая внутренняя неудовлетворенность тем, как это реализовано сегодня. И я хотел бы поделиться идеями, как это можно было бы сделать в будущем и услышать от вас какие-то отзывы, да и просто понять — а нужно ли вообще с этим заморачиваться?
Исходная задача
Допустим, нам в шаблоне нужно добавить следующие тексты:1. Это новый блог
2. Блог называется «Новости»
3. В этом блоге 21 топик и 123 комментария
Важно: Здесь название блога «Новости» и число топиков и комментариев берется из объекта блога прямо в шаблоне.
Как это решается сейчас
В языковом файле прописываем:'this_is_a_new_blog' => 'Это новый блог',
'blogs_title_is' => 'Блог называется',
'in_this_ blog ' => 'В этом блоге',
'topics ' => 'топик;топика;топиков',
'comments ' => 'комментарий;комментария;комментариев',
'and' => 'и',
А в шаблоне мы оформляем так:
1. {$aLang.this_is_a_new_blog}
2. {$aLang.blogs_title_is} «{$oBlog->getTitle()}»
3. {$aLang.in_this_ blog} {$oBlog->getTopicCount()} {$oBlog->getTopicCount()|declension:$aLang.topics} {$aLang.and} {$oBlog->getCommentCount()} {$oBlog->getCommentCount()|declension:$aLang.comments}
В общем-то, задача решается. Но мне не нравятся следующие моменты:
- использование переменной $aLang — возможно, это не очень существенно, но не нравится мне, что мы берем массив (а он может быть весьма приличный по размеру) со всеми текстовками сайта и пихаем его во все шаблоны; хотелось бы это решать вызовом функции
- в силу определенных технологических особенностей мы не можем, скажем, вместо $aLang.plugin.demo.some_text (если такой текстовки нет) вывести просто SOME_TEXT или PLUGIN.DEMO.SOME_TEXT, что затрудняет отладку сайта
- есть определенные сложности со склонениями, числительными и прочими нюансами, если это нужно проделать на разных языках. Иногда потребуется писать специальный языковой плагин для Smarty.
Справедливости ради надо добавить, что текст №2 в примере в нынешней реализации может быть и иначе выполнен. Для этого в языковом файле должна быть такая запись:
'blogs_title_is' => 'Блог называется «%%title%%»'
А в шаблоне надо записать так:
{$aLang.blogs_title_is|ls_lang:"title%%`$oBlog->getTitle()`"}
Но, на мой взгляд, общую «картину мира» это мало меняет
Как предлагается делать это в будущем
Языковой файл:' This is a new blog ' => 'Это новый блог',
'Blog\'s title is «%s» ' => 'Блог называется «%s»',
'There\'re %n_topics & %n_comments in this blog' => ' В этом блоге %{_1:топик;_2-_4:топика;_0,_5-_9:топиков} и %{_1:комментарий;_2-_4:комментария;_0,_5-_9:комментариев}',
Шаблон:
1. {{This is a new blog}}
2. {{Blog\'s title is «%s»|$oBlog->getTitle()}}
3. {{There\'re %n_topics & %n_comments in this blog|$oBlog->getTopicCount(),$oBlog->getCommentCount()}}
Думаю, из примера понятно, что значит в языковом файле выше «_1» — это число, имеющее при делении на десять в остатке 1.
Для последнего примера можно в языковом файле записать и так:
'There\'re %n_topics & %n_comments in this blog' => ' В этом блоге %{_1:топик;_2-_4:топика;_:топиков} и %{_1:комментарий;_2-_4:комментария;_:комментариев}',
Здесь знак подчеркивания без всяких цифр «_» означает любое число.
Но ведь у нас, как мы помним, текстовки могут быть в разных файлах, и они подгружаются в разные секции. Ок, текстовка из плагина Demo будет выглядеть так:
{{plugin.demo}{This is a new blog }}
Разумеется, в качестве параметров могут использоваться не только числа. Например, в шаблоне есть такой код:
{{He has a %s_face|$oMan->FaceDesc()}}
А в языковом файле прописано:
' He has a %s_face ' => 'У него %{красивое:личико;кривая:морда;_:лицо} ',
То сами можете догадаться, что будет выведено.
А если нужная текстовка отсутствует в языковых файлах? Тогда приведенные выше примеры при выводе будут выглядеть так:
1. This is a new blog
2. Blog's title is «News»
3. There're 21 topics & 123 comments in this blog
Т.е. тексты будут взяты как есть, и подстановки будут произведены прямо в них.Что еще из этого может получиться
В общем-то, на этом можно и закончить. Но логически получается так, что если эта технология будет реализована, то для особо пытливых и находчивых она открывает довольно широкие возможности для «выкаблучивания». Например, если в языковом файле мы напишем так:'There\'re %n_topics & %n_comments in this blog' => ' В этом блоге %{0:нет топиков; _:есть топики}',
То получим запись «В этом блоге нет топиков», если число топиков равно нулю, и «В этом блоге есть топики» в противном случае. А вот про комментарии не будет ни слова. А если нужно наоборот, только про комментарии написать? Тогда формат текста будет такой:
'There\'re %n_topics & %n_comments in this blog' => ' В этом блоге %{_: } %{0:нет комментариев;_:есть комментарии }',
Т.к. первый параметр при любом значении (стоит подчеркивание) ничего не даст (после двоеточия – пусто), то получим «В этом блоге нет комментариев» или «В этом блоге есть комментарии».
Плюсы и минусы
Плюсы нового подхода – гибкость, более легкая адаптируемость, упрощается процесс создания шаблонов и локализация (на исходном языке можно гораздо меньше текстовок выносить в отдельный файл).А основной минус я вижу один: Это окончательный уход шаблонов от совместимости ЛС.
Хотя, возможно, я упускаю какие-то нюансы, которые могут перекрыть все преимущества нового подхода. Поэтому хотелось бы услышать мнение сообщества на этот счет.
А много ль шаблонов на ЛС?
Уход от совместимости чего либо — это не минус, а закономерность имхо. Очень скорый уход, возможно, минус ))))))