Создание многоязычных веб-приложений с помощью JSTemplater 1.0Alfa
Создание многоязычных веб-приложений с помощью JSTemplater 1.0Alfa
Исходные тексты (ZIP)
Доброго времени суток уважаемые читатели !
В этой статье я бы хотел поговорить о многоязычных приложениях, а именно создание оных в контексте технологии JavaScript и XHTML, без использования при этом произвольных серверных технологий.
Каждый из нас, кто когда-то непосредственно сталкивался с разработкой многоязычных приложений, знает всю их многогранность и в некоторых случаях неоднозначность создания. Так например, иногда клиенту необходимо отправить, предположим, опросник, в котором бы клиент указал, что именно он хочет, как он этого хочет, и что может за это отдать.
Вот тут и появляется вопрос: "А если клиент иностранец ?", то есть уже из этого вопроса, появляется ещё один вопрос: "Как же рациональнее всего реализовать многоязычность ?". Конечно, можно изначально перевести документ на несколько языков, после же отправлять заказчику один из них. Да, это безусловно допустимо, и наиболее используемо в контексте современных веб-студий и прочих компаний так или иначе ведущих диалог с заказчиками.
Я же выбрал иной подход, который считаю немного более гибкий и практичный, при чём ничем не уступающий "ручному" разбиению на языки. Суть его заключается в введении системы шаблонирования, и преобразовании языковых единиц в переменные шаблона, которые в последствии будут заменены в теже языковые единицы, однако относящиеся к другому языку. Пример схожего механизма можно наблюдать повсеместно в системах, так или иначе использующих шаблонирование в интерфейсе или в целом во внутренней реализации системы. Так ярким примеров систем-шаблонизаторов могут служить такие системы как PatTemplaters, Smarty и прочее. В них результирующие данные формируются на основании некоторых входящих данных (переменных шаблона) которые "подставляются" в шаблон, после чего выполняются в контексте заданного набора алгоритмической логики шаблона, и возвращаются ввиде обработанного текста.
В нашем случае всё аналогично, однако парсер JSTemplater 1.0Afla создан в расчете на функционирование на стороне клиента, и в качестве входящих данных принимает не текст шаблона, а весь текущий HTML-документ, начиная тегом <body>, и закачивая местом вызова метода для рендеринга служебных конструкций, которые были обнаружены в HTML-документе.
Но говорим мы сейчас не о предмете парсера JSTemplater 1.0Alfa, а о том как его использовать на практике. Но ведь для этого вам необходимо как минимум скачать его, для этого перейдите по следующему адресу: http://e-code.tnt43.com/sources/jsTemplater.zip (ZIP-packed archive).
Для подключения парсера к вашему документу просто подключите JS-скрипт, находящийся в архиве к вашему документу в разделе <HEAD>. Далее необходимо указать идентификатор тега <body>, и установить его значение в "body". Это необходимо для получения доступа к узлам элементов XHTML-документа.
Так же принципиальныс условием, для того, чтобы документ был корректно обработан, является вызов функции JSTemplater.init() именно перед закрывающим тегом </body>, что является необходимым для того, чтобы парсер получил все узлы документа, а не только те, которые успели подгрузится в настоящее время.
Что ж, вот скелет минимального приложения:
Листинг 1.1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html;
charset=windows-1250">
<meta name="generator" content="PSPad editor, www.pspad.com">
<title></title>
<script type=text/javascript src=jsTemplater.js></script>
</head>
<body id=body>
<script type=text/javascript>
<!--
JSTemplater.init();
-->
</script>
</body>
</html>
Итак, чтобы больше не останавливаться на описании технологии шаблонизатора, я приведу список из функций, которые мы будет в дальнейшем использовать, а так же их семантики:
ФункцияПояснение
| JSTemplater.init() | Функция после вызова которой происходит начало обработки. Необходимо вызывать перед закрывающим тегом </body> |
| JSTemplater.registerLib(src, type) | Происходит подключение внешней библиотеки к текущему документу. Библиотека - файл src, формата type (text/javascript, text/css). Добавление происходит в раздел <head> |
| JSTemplater.assignVariable(name,value) | Объявить переменную шаблона с именем name и значением value |
| JSTemplater.makeArray(name) | Создать массив name |
| JSTemplater.append2Array(name, value) | Добавить скалярное значение value к массиву name |
| JSTemplater.append2ArrayIndex(arr, name,value) | Добавить элемент value, скалярного типа, к массиву name, находящегося в массиве arr (двумерный массив) |
| JSTemplater.loadLibs() | Загрузка зарегистрированных (см. JSTemplater.registerLib) библиотек. |
Что ж, а теперь давай-те непосредственно о многоязычности. Для того чтобы раскрыть тему статьи, я предлагаю рассмотреть реальную ситуацию с некоторой формой, предназначеной для заказчиков, с двумя условиями: она доступена на 3-х языках, она должена быть ориэнтирована на обработку на стороне клиентского интерфейса.
Сейчас, мы создадим небольшой опросник, который будет содержать в себе: 5 информационных полей (название поля, поле ввода), 3 кнопок для переключения между языками(рус., англ., франц.).
Она будет простейшей:
Листинг 1.2
<div class=langs>
<button onclick=setLang("ru");>Хочу на русском !</button>
<button onclick=setLang("en");>Im want it in English !</button>
<button onclick=setLang("fr");>Je veux en francais!</button>
</div>
<form action=http://somehost.somedomain/formProceed method=post>
Введите ваше имя: <input type=text name=first/><br/>
Откуда вы узнали о нашей компании? <br/>
<input type=text name=wayf><br/>
Как вы оцениваете качество предоставляемых нами услуг ?<br/>
<select name=quality>
<option value=0>Отлично</option>
<option value=1>Хорошо</option>
<option value=2>Удовлетворительно</option>
<option value=3>Посредственно</option>
<option value=4>Плохо</option>
</select><br/>
<input type=submit name=send value=Отправить нам информацию/>
</form>
Как видите, в нашем случае у нас много текстовых данных, которые можно по их семантике разбить на отдельные строковые константы, а некоторые после аналогичного приведения распределяются относительно массива значений (пример тому значения списка "quality").
Каждому изменяемому текстовому значению документа будет соответствоватьпеременная, которая обычно или ставится в значении имени элемента управления напротив неё с прибавлением постфикса "_l", либо просто семантически близкое к данному название.
Так, у нас будут следующие константы:
lang {en, fr, ru} //массив с надписями к кнопочкам изменения языка
yname //текст напротив элемента yname
wayf //аналогично
quality {0,1,2,3,4} //массив значений оценки качества
Ещё нужно учесть, что некоторые константы имеют одинаковое значение(я) относительно языка, а другие объявляются относительно выбранного сейчас языка. В нашем случае, мы будем использовать для этих целей оператор switch(){default:break;} и набор операторов case, которые будут попросту объявлять константы в зависимости от выбранного языка.
А как мы будет определять какой выбран язык ? Через QUERY_STRING.
Вот функции setLang(val:String):Void: и getLang():String, которые будут использоваться для установки/получения текущего параметра языка.
Листинг 1.3
function setLang(value){
document.location.href=?lang=+value;
}
function getLang(){
if(document.location.search){
lang=document.location.search.split(=);
lang=lang[1];
}else{
lang=ru;
}
return lang;
}
Теперь же мы можем непосредственно задать языковые схемы:
Листинг 1.4
function definitions(){
JSTemplater.assignVariable("lang",getLang());
JSTemplater.makeArray("quality");
JSTemplater.makeArray("lang");
JSTemplater.append2ArrayIndex("lang","ru","Хочу на русском !");
JSTemplater.append2ArrayIndex("lang","en","Im want it in English !");
JSTemplater.append2ArrayIndex("lang","fr","Je veux en francais!");
switch(getLang()){
case ru:
//Русская языковая схема
JSTemplater.assignVariable("yname","Введите ваше имя");
JSTemplater.assignVariable("wayf","Откуда вы узнали о нашей компании ?");
JSTemplater.append2Array("quality","Хорошо");
JSTemplater.append2Array("quality","Отлично");
JSTemplater.append2Array("quality","Посредственно");
JSTemplater.append2Array("quality","Плохо");
break;
case en:
//Английская языковая схема
JSTemplater.assignVariable("yname","Enter your name");
JSTemplater.assignVariable("wayf","Where do you found us?");
JSTemplater.append2Array("quality","Good");
JSTemplater.append2Array("quality","Very good");
JSTemplater.append2Array("quality","Average");
JSTemplater.append2Array("quality","Bad");
break;
case fr:
//Французская языковая схема
break;
}
}
В данном листинге продемонстрировано задание текстовых констант, на значение которых будут изменятся служебные конструкции в исходном коде шаблона, после обращения к функции init().
Как видите всё предельно просто. И для большей наглядности мы сейчас перейдём к исходному коду шаблона, который будет обрабатыватся:
Листинг 1.5
//....
<body id=body>
Значение текущего идентификатора языковой схемы: <strong>{^lang^}</strong>
<div class=langs>
<button onclick=setLang("ru");return false;>{^lang{ru}^}</button>
<button onclick=setLang("en");return false;>{^lang{en}^}</button>
<button onclick=setLang("fr");return false;>{^lang{fr}^}</button>
</div>
<form action=http://somehost.somedomain/formProceed method=post>
{^yname^}: <input type=text name=first/><br/>
{^wayf^} <br/>
<input type=text name=wayf><br/>
{^lang{quality_label}^}<br/>
<select name=quality>
<option value=0>{^quality{0}^}</option>
<option value=1>{^quality{1}^}</option>
<option value=2>{^quality{2}^}</option>
<option value=3>{^quality{3}^}</option>
</select><br/>
<input type=submit name=send value=Отправить нам информацию/>
</form>
//...
Вот и всё на этом. Наше приложение полностью функционально, и вполне корретно работает, при этом расширение не составляет особых проблем.
Ну, для тех, кому лень почитать спецификацию конструкций JSTemplator (http://e-code.tnt43.com/specs/t0.005.pdf) версии 1.0, приведу синтаксис основных конструкций:
| Маска | Название |
| (open_bracket)+(.*)(close_bracket)+ | Обращение к переменной |
| (open_bracket)+((.*)\{([0-9]*)\})(close_bracket)+ | Обращение к числовому индексу массива |
| (open_bracket)+((.*)\{(.*)\})(close_bracket)+ | Обращение к литеральному индексу массива |
При этом open_bracket и close_bracket по умолчанию "{^" и "^}", и могут быть изменены с помощью специальной функции библиотеки JSTemplater.
Всё, считаю тему на этом исчерпаной, если будут вопросы прошу отправлять их мне на почту: LoRd1990@gmail.com
www.codenet.ru
Языки программирования 29-06-2008 Обработка XML+XSL на Ruby 16-10-2008 Языки программирования В данном цикле статей изложены основные принципы программирование на Ruby. Ruby ("рубин") - сравнительно молодой интерпретируемый
язык программирования общего назначения, приобретающий все большую и большую популярность.
Курс ориентирован на читателей, которые уже знают какой-либо язык программирования и понимают магию, с помощью которой из набора разрозненных операторов получается нечто действительно полезное. [Александр Неткачев] ...
Использование JavaScript для создания интерактивных Web-страниц 20-08-2008 Языки программирования Обобщенно гипертекстовая информационная система состоит из множества информационных узлов, множества гипертекстовых связей, определенных на этих узлах, и инструмента манипулирования узлами и связями. Технология World Wide Web - это технология ведения гипертекстовых распределенных систем в Internet, и, следовательно, она должна удовлетворять общему определению таких систем. Это значит, что все вышеперечисленные компоненты гипертекстовой системы ... |