Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Создание многоязычных веб-приложений с помощью JSTemplater 1.0Alfa

Автор: Кирилл Карпенко
http://e-code.tnt43.com/
14 декабря 2007 года

Исходные тексты (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");'>I'm 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", либо просто семантически близкое к данному название.

Так, у нас будут следующие константы:

  1. lang {en, fr, ru} //массив с надписями к кнопочкам изменения языка
  2. yname //текст напротив элемента yname
  3. wayf //аналогично
  4. 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","I'm 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

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог