Opera

индекс
155,07

Пишем многоязычное приложение Opera Unite (часть 1)

К сожалению, пока что Opera не поддерживает локализацию виджетов методом, предложенном в стандарте W3C, но даже если будет поддерживать, то это касается только серверной стороны, и, видимо, только языка сервера. Поэтому сделаем всё сами, учитывая, что языки браузера-сервера и браузера-клиента в общем случае разные.

Получение со стороны сервера языка отсылаемой к клиенту информации

Как определить язык клиента на сервере? — по заголовку HTTP Accept-Language. Как до него добраться? — через метод getRequestHeader или свойство headers объёкта типа WebServerRequest. А дальше его по алгоритму, описанному в RFC, обрабатывать? — да. Для этого я написал функцию, принимающую WebServerRequest и список поддерживаемых локализаций, и выдающую предпочитаемую клиентом локализацию:
function getLanguageNameForRequest(Request,SelectedArray){
	var HeaderCollection=Request.getRequestHeader("Accept-Language");
	var AcceptString="";
	if(HeaderCollection!=null)if(HeaderCollection.length>=1){
		//HeaderCollection является DOMStringList и не имеет метода join, поэтому порнография
		for(var i=0,AcceptString=HeaderCollection.item(0); i<HeaderCollection.length-1;){
			i++;
			AcceptString+=","+HeaderCollection.item(i);
		}
	}
	var AcceptArray=AcceptString.replace(" ","").split(",");
	//Смотри RFC2616,  #14.4 Accept-Language
	//http://tools.ietf.org/html/rfc2616#section-14.4
	var Lang=SelectedArray[0],Qu=-Infinity;
	for(var i in AcceptArray){
		var l,q,lq;
		lq=AcceptArray[i].split(";");
		l=lq[0];q=1;
		try{
			if(lq[1].substring(0,2)==="q="){
				q=parseFloat(lq[1].substring(2));
			}
		}catch(err){
			q=1;
		}
		if(SelectedArray.indexOf(l)>=0){
			if(q>Qu){
				Lang=l;
				Qu=q;
			}
		}
	}
	
	return Lang;
}
Пример вызова
Например, если клиент отправил в заголовке Accept-Language строку «ru,ru-RU;q=0.9,en;q=0.8,de;q=0.7», а на сервере поддерживаются языки «ru» и «en», то getLanguageNameForRequest вернёт «ru»:
window.onload = function () {opera.io.webserver.addEventListener('_index', function(RequestEvent){
	RequestEvent.connection.response.writeLine("Язык клиента: "+getLanguageNameForRequest(RequestEvent.connection.request,["ru","en"]));
	RequestEvent.connection.response.close();
}, false);}
Почему не использовать вместо всего этого UserAgent? Потому что в нём передаётся язык интерфейса браузера, а не страниц.

Получение со стороны сервера языка выводимой на сервер информации

Особенность технологии Opera Unite в том, что серверный скрипт взаимодействует не только с людьми, которые получают через браузеры-клиенты HTML, но и с человеком, который сидит за браузером-сервером, непосредственно через различные API, например отсылкой сообщений через widget.showNotification. К счастью, для серверного кода доступен тот же DOM, что и для обычной страницы, то есть window.navigator.language работает и выдаёт язык интерфейса браузера-сервера. Обёртываем в аналогичную предыдущему случаю функцию, выбирающую язык из доступных:
function getLanguageNameForServer(SelectedArray){
	var l=window.navigator.language
	return (SelectedArray.indexOf(l)>=0)?l:SelectedArray[0];
}

widget.showNotification("Язык сервера:"+getLanguageNameForServer(["en","ru","de"]));

Создание инфраструктуры для локализации приложения в целом

Так как одним из важнейших преимуществ Opera Unite является возможность использовать один и тот же код Javascript одновременно и в серверной, и в клиентской частях приложения, то хотелось бы при создании API для локализации это свойство не потерять, то есть язык отдаваемых строк должен неявно определяться местом выполнения кода, который их просит. Об этом будет вторая часть поста, если я её напишу.
+12
14 октября 2009, 15:59
10

комментарии (10)

+2
Xpeh #
Хотелось бы это в блог Opera запихнуть…
+2
Xpeh #
Спасибо, запихнул
–2
xariton #
ох, как же было бы здорово, если бы все браузеры (в том числе и Опера) поддерживали w3c. Сколько бы головной боли в оптимизации удалось бы избежать.
+4
SKYnv #
вот как раз опера печется больше всех по моему о них ) у них в w3c много народу работает.
+2
xariton #
да, согласен с Вами. я имел в виду, что хорошо бы разработчикам браузеров начать активней взаимодействовать и идти более-менее в одном направлении унификации поддержки разметки.
0
Xpeh #
Ну в данном случае, учитывая, что редактором спецификации является сотрудник Оперы, надеемся на скорую реализацию…
+1
pepelsbey #
Спасибо за заметку )
Механизм локализации приложений пока находится в разработке, так что этот способ будет полезен.
0
Xpeh #
А когда он примерно будет, хотя бы в финале 10.10 или позже?
0
pepelsbey #
Думаю, что сегодняшняя бета 10.10 говорит о скором выходе финальной версии, а эта фича с локализацией является серьёзным изменением в работе виджетов, так что у меня есть ощущение, что в финал это не войдёт.
0
avenu #
Я недавно работал с похожей проблемой, определения страны, откуда пришел запрос. В итоге остановился на легковесном варианте — делаю запрос к сервису, который возвращает по ip страну. В принципе, на основе этого можно примерно и язык предполагать.

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