Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Функция поддержки мультиязычности. (https://javascript.ru/forum/misc/21838-funkciya-podderzhki-multiyazychnosti.html)

fiw 26.09.2011 14:58

Функция поддержки мультиязычности.
 
Сегодня написал функцию, на входе она получает идентификатор фразы, и доп. переменные, на выходе возвращает готовую фразу.

Вопрос: Как этот код приспособить к поддержки других языков?
Желательно хранить фразы в отдельных внешних файлах.
И подгружать их в зависимости от установленного у пользователя языка.

Отрывок кода:
// Массив содержащий все фразы используемые сайтом
var language = {
// ---- тут их может быть сколь угодно.
photos_count: 'Фото %l из %l'
};


function getFrase(langKey){
	var value, langArr = language, key = langKey, a = arguments, l = a.length;
	
	for (var k in langArr) {
		if (k === key){
			value = langArr[k];
			if (l>=2){
				for(var i = 1; i < l; ++i) {
					value = (value || '%l').replace('%l', a[i]);				
				}
			}
			
		}
	}	
	
	return value;
}


document.getElementById('div_photos_count').innerHTML = '<b>'+getFrase('photos_count',1,20)+'</b>';

Мы получаем: <div id="div_photos_count">Фото 1 из 20</div>

ksa 26.09.2011 15:14

fiw, мультиязычность, как правило, делают на сервере... Не на клиенте... Оно так сподручнее. :)

fiw 26.09.2011 15:20

ksa,
А почему бы не на клиенте сделать?
Я вот к примеру, хочу чтобы в зависимости от языка, подгружался тот или иной lang.js
В котором массив, содержащий все по текущему языку.

Триви 26.09.2011 15:49

Цитата:

Сообщение от fiw (Сообщение 128136)
ksa,
А почему бы не на клиенте сделать?

Потому что данные хранятся на сервере в базе на разных языках
и выводятся в зависимости от выбранного языка..
Какой такой потайной эротический смысл в том,
чтобы подгружать разные js-скрипты в зависимости от языка???
Почему не сделать эти скрипты языконезависимыми? ;)

fiw 27.09.2011 04:24

Так в том то и прикол, чтобы не делать запросы в БД за этими языками, пускай фразы будут в JS храниться.
А в зависимости от языка используется тот или иной файл.
Тем более если учесть что большая часть сайта динамическая.

ksa 27.09.2011 09:19

Цитата:

Сообщение от fiw
Так в том то и прикол

В работе "приколы" не лучший помошник... :) А вот работа с БД как нельзя кстати. ;)

walik 27.09.2011 13:57

Цитата:

Сообщение от fiw
чтобы не делать запросы в БД за этими языками

Можно и не только в БД это делать, можно и в файлах хранить, и подключать нужный.

А насчет вашей функции, зачем в цикле проходить по массиву для того что бы найти ключ, а не просто сразу обратится ?
value = langArr[key];

DjDiablo 27.09.2011 14:31

Если я правильно понимаю. То поисковики будут индексировать сайт очень криво, так как javascript они не интерпритируют. Короче вместо сайта они покажут шаблон для подстановки слов.

fiw 27.09.2011 15:48

Цитата:

Сообщение от DjDiablo (Сообщение 128297)
Если я правильно понимаю. То поисковики будут индексировать сайт очень криво, так как javascript они не интерпритируют. Короче вместо сайта они покажут шаблон для подстановки слов.

Ну это не новостной сайт )
Это как рабочая программа) Там индексировать ничего не нужно.

fiw 27.09.2011 15:49

Цитата:

Сообщение от walik (Сообщение 128289)
А насчет вашей функции, зачем в цикле проходить по массиву для того что бы найти ключ, а не просто сразу обратится ?
value = langArr[key];

А если этого значения нету в массиве? Как быть?

walik 27.09.2011 17:47

Условие поставить:
if (langArr[key])
   value = langArr[key];
else
   value = 'Not found';

with-love-from-siberia 27.09.2011 22:26

Для обычного сайта так делать смысла нет. А вот для самостоятельных приложений (HTA, XUL) так делать имеет смысл.

Цитата:

Сообщение от fiw
А если этого значения нету в массиве?

Лучше так сделайте:

var texts = {
    'Yes': 'Да', 
    'No': 'Нет', 
    'Cancel': 'Отмена'
};

function translate(value)
{
    return texts[value] || value;
};

alert([
    translate('Delete this file?'), 
    translate('Yes'), 
    translate('No')
]);

melky 28.09.2011 21:56

Цитата:

Сообщение от with-love-from-siberia (Сообщение 128338)
Для обычного сайта так делать смысла нет.

а что, если сайт на народе, и больше сделать ну никак не получится?

aiky 01.10.2011 21:46

var lc = function(id){
  if(!lc.base[id] || !lc.base[id][lc.is[lc.cur]]) return id;
  return lc.base[id][lc.is[lc.cur]];
};

lc.is = {
  'ru':0,
  'en':1
};

lc.cur = 'en';

lc.init = function(){
  var lc = navigator.browserLanguage;
  if(!lc) lc = navigator.language;
  lc = lc.substring(0,2).toLowerCase();
  if(typeof(lc.is[lc]) != 'undefined') this.cur = lc;
};

lc.base = {
  'ru':['Русский','Russian'],
  'en':['Английский','English'],
  ...
}

melky 01.10.2011 21:55

нет возможности запомнить язык (например, я хочу сидеть на английском).

lc.base сильно ударит по памяти, если фраз будет около девяти тысяч.

aiky 01.10.2011 22:09

Цитата:

Сообщение от melky
нет возможности запомнить язык (например, я хочу сидеть на английском).

Что мешает изменять lc.cur?

Цитата:

Сообщение от melky
lc.base сильно ударит по памяти, если фраз будет около девяти тысяч.

Цитата:

Сообщение от melky
а что, если сайт на народе, и больше сделать ну никак не получится?

Разве эти 2 фразы не противоречат друг другу?
Где-то память все равно придется выкусывать, чудес не бывает.

melky 01.10.2011 22:28

Цитата:

Сообщение от aiky (Сообщение 129101)
Что мешает изменять lc.cur?
Разве эти 2 фразы не противоречат друг другу?
Где-то память все равно придется выкусывать, чудес не бывает.

неа. я о другом говорил

для каждого слова будут храниться переводы для каждого языка?
lc.base = {
  'ru':['Русский','Russian'],
  'en':['Английский','English'],
  ...
}

можно просто хранить переводы только для текущего языка, и заменять существующий объект другим при обновлении значения языка

aiky 01.10.2011 22:33

Цитата:

Сообщение от melky
можно просто хранить переводы только для текущего языка, и заменять существующий объект другим при обновлении значения языка

Так можно вообще не заморачиваться и подгружать асинхронно словарь при смене языка неважно из БД или файла, но речь ведь шла о полной реализации на стороне клиента.

melky 01.10.2011 22:57

Цитата:

Сообщение от aiky (Сообщение 129116)
Так можно вообще не заморачиваться и подгружать асинхронно словарь при смене языка неважно из БД или файла, но речь ведь шла о полной реализации на стороне клиента.

бд в файле на языке JS - чем вам не реализация?

aiky 01.10.2011 23:02

Цитата:

Сообщение от melky
бд в файле на языке JS - чем вам не реализация?

чем это отличается от lc.base?

..ессно можно сделать подмену lc.base с необходимым словарем при смене языка, несколько увеличив при этом общий размер словарей за счет дублирования ключей, но этот вопрос скорее технический чем принципиальный:

ru.js:
lc.base = {
  'ru':'Русский',
  'en':'Английский',
  ...
}



en.js:
lc.base = {
  'ru':'Russian',
  'en':'English',
  ...
}

fiw 14.10.2011 17:41

Идеально это при смене языка в браузере менять ссылку на словарь.
если русский язык, то файл ru.js, при смене языка, средствами DOM удаляем привязанный словарь, и подгружаем сразу необходимый нам. Например en.js или es.js
Вот как именно это реализовать?

aiky 15.10.2011 05:45

Цитата:

Сообщение от fiw
Вот как именно это реализовать?

ru.js:
lc.base = {
  'ru':'Русский',
  'en':'Английский',
  ...
}



en.js:
lc.base = {
  'ru':'Russian',
  'en':'English',
  ...
}


var lc = function(id){
  if(!lc.base[id]) return id;
  return lc.base[id];
};

lc.is = {
  'ru':0,
  'en':1
};

lc.def = 'en';

lc.init = function(){
  var l = navigator.browserLanguage;
  if(!l) l = navigator.language;
  l = l.substring(0,2).toLowerCase();
  if(typeof(lc.is[l]) != 'undefined') lc.load(l);
  else lc.load(lc.def);
};

lc.load = function(l){
  var e = document.createElement('script',{
    'type':'text/javascript',
    'src':l + '.js'
  });
  e.error = e.onload = e.readystatechange = function(){
    if(!e.loaded && (!e.readyState || e.readyState == 'loaded' || e.readyState == 'complete')){
      e.loaded = 1;
      e.onerror = e.onload = e.onreadystatechange = null;
      e.parentNode.removeChild(e);
    }
  };
  var head = document.getElementsByTagName('head');
  if(head.length) head = head[0];
  head.appendChild(e);
}

fiw 18.10.2011 16:51

А обновление переменных в странице при подключении нового словаря сразу же произойдет?


Часовой пояс GMT +3, время: 07:47.