Верх страницы
Время для прочтения: 2 мин. 15 сек.

Умный переключатель языков

Обычно переключение языков на сайте сделано обычными ссылками вида |ru|en|cn|, которое никак не отслеживает на какой странице пользователь решил поменять язык, и просто переходит на главную страницу сайта с другим языком.

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

Разметка HTML-кода:

<ul>
   <li><a onclick="return switch_language('ru', 'ru')" href="/ru/">ru</a></li>
   <li><a onclick="return switch_language('ru', 'en')" href="/en/">en</a></li>
   <li><a onclick="return switch_language('ru', 'cn')" href="/cn/">cn</a></li>
</ul>

Первый параметр в функции — текущий язык, у меня он определяется в РНР-коде и вставляется в шаблон. Как понятно из примера — это вариант, когда текущий язык — русский(ru).

JavaScript код:

/ Аналог РНР-функции str_replace

function str_replace( search, replace, subject ) {

	if ( !( replace instanceof Array ) ) {
		replace = new Array( replace );
		if ( search instanceof Array ) {
			while ( search.length > replace.length ) {
				replace[ replace.length ] = replace[ 0 ];
			}
		}
	}

	if ( !( search instanceof Array ) ) search = new Array( search );
	while ( search.length > replace.length ) {
		replace[ replace.length ] = '';
	}

	if ( subject instanceof Array ) {
		for ( k in subject ) {
			subject[ k ] = str_replace( search, replace, subject[ k ] );
		}
		return subject;
	}

	for ( var k = 0; k - 1 ) {
		subject = subject.replace( search[ k ], replace[ k ] );
		i = subject.indexOf( search[ k ], i );
	}
}

return subject;

}

// Аналог РНР-функции parse_url
function parse_url( str, component ) {

	var o = {
			strictMode: false,
			key: [ "source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor" ],
			q: {
				name: "queryKey",
				parser: /(?:^|&)([^&=]<em>)=?([^&]</em > ) / g
		},
		parser: {
			strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]<em>):?([^:@]</em > ) ) ? @ ) ? ( [ ^: \/?#]<em>)(?::(\d</em > ) ) ? ) ) ? ( ( ( ( ? : [ ^ ? #\/]<em>\/)</em > )( [ ^ ? # ] < em > ) )( ? : \ ? ( [ ^ # ] < /em>))?(?:#(.<em>))?)/,
			loose: /^(?:(?![^:@]+:[^:@\/]</em > @ )( [ ^: \/?#.]+):)?(?:\/\/\/?)?((?:(([^:@]<em>):?([^:@]</em > ) ) ? @ ) ? ( [ ^: \/?#]<em>)(?::(\d</em > ) ) ? )( ( ( \/(?:<a href="?![^?#\/]*.[^?#\/.]+(?:[?#]|$)">^?#</a > ) < em > \/?)?([^?#\/]</em > ) )( ? : \ ? ( [ ^ # ] < em > ) ) ? ( ? : #( . < /em>))?)/ // Added one optional slash to post-protocol to catch file:/// (should restrict this)
			}
		};

		var m = o.parser[ o.strictMode ? "strict" : "loose" ].exec( str ),
			uri = {},
			i = 14;
		while ( i-- ) {
			uri[ o.key[ i ] ] = m[ i ] || "";
		}
		switch ( component ) {
		case 'PHP_URL_SCHEME':
			return uri.protocol;
		case 'PHP_URL_HOST':
			return uri.host;
		case 'PHP_URL_PORT':
			return uri.port;
		case 'PHP_URL_USER':
			return uri.user;
		case 'PHP_URL_PASS':
			return uri.password;
		case 'PHP_URL_PATH':
			return uri.path;
		case 'PHP_URL_QUERY':
			return uri.query;
		case 'PHP_URL_FRAGMENT':
			return uri.anchor;
		default:
			var retArr = {};
			if ( uri.protocol !== '' ) {
				retArr.scheme = uri.protocol;
			}
			if ( uri.host !== '' ) {
				retArr.host = uri.host;
			}
			if ( uri.port !== '' ) {
				retArr.port = uri.port;
			}
			if ( uri.user !== '' ) {
				retArr.user = uri.user;
			}
			if ( uri.password !== '' ) {
				retArr.pass = uri.password;
			}
			if ( uri.path !== '' ) {
				retArr.path = uri.path;
			}
			if ( uri.query !== '' ) {
				retArr.query = uri.query;
			}
			if ( uri.anchor !== '' ) {
				retArr.fragment = uri.anchor;
			}
			return retArr;
		}
	}

	// Собственно, само переключение
	function switch_language( from, to ) {
		// Если языки совпадают - пропустить
		if ( from == to ) return false;
		// Получить УРЛ
		var url = document.location.href;
		// Распарсить
		var purl = parse_url( url );
		// Взять ток путь
		var path = purl.path;
		var nurl;
		// Вариант для главной страницы
		if ( path == '/' ) {
			nurl = url + to + '/';
			// Для внутренних страниц
		} else {
			nurl = str_replace( '/' + from + '/', '/' + to + '/', url );
			//nurl = url.replace(/from/, to);
		}
		// Переход по новому адресу
		document.location.href = nurl;
		return false;
	}

Пример работы вы можете посмотреть на сайте Шанхайской Организации Сотрудничества (ШОС)

Комментарии
Подписаться
Уведомить о
guest

16 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
Степан
Степан
15 лет назад

А зачем вы заменили url.replace на str_replace?

Дмитрий
Дмитрий
12 лет назад

Здравствуйте!
Спасибо за статью. Я не вполне хорош в JS, прямо скажем «ламер».
Будьте любезны, объясните можно ли этот метод встроить в HTML5? И если можно, то как это правильно реализовать? Как прописать в коде ссылку на скрипт.
А-то у меня переключение работает на сайте, а «умное» не прикручивается никак.
Заранее спасибо!

Дмитрий
Дмитрий
12 лет назад

В хэде такая строка:

скрипт отдельным файлом, как видите, в соответствующей папке
кнопки переключения в блоке меню вписались аккуратно (эстетически) в виде маленьких подпунктиков в стороне с «подсветкой» текущего языка, в коде это выглядит так:

<a href="/en/" rel="nofollow">en</a>
<a href="/ru/" rel="nofollow">ru</a>
<a href="/es/" rel="nofollow">es</a>
Владимир
11 лет назад

Не знаю как остальные, а я не наблюдаю интелектуального переключения языков на указанном сайте «Шанхайской Организации Сотрудничества (ШОС)».
Находясь на странице «Кто есть кто?» при переключения языка загружается домашняя страница английской версии, а не страница «Who is who?».
Либо скрипт не работает, либо с сайтом что то не то.

Владимир
11 лет назад
Ответить на  Кобзарёв Михаил

В таком случае попробую Ваш скрипт На своем сайте, если не возражаете.
О результатах отпишусь.

max_7548
max_7548
10 лет назад

В строке 29 лишняя фигурная скобка.
В строке 25 не хватает «;» точки с запятой.

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

mihdan
10 лет назад
Ответить на  max_7548

Спасибо за наводку об ошибках. Поправлю

Ольга Крахмалёва
Ольга Крахмалёва
10 лет назад

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

mihdan
10 лет назад
Ответить на  Ольга Крахмалёва

Тогда этот вариант не для вас.

Ольга Крахмалёва
Ольга Крахмалёва
10 лет назад
Ответить на  mihdan

Он не для кого. Он даже в демо версии не работает, о чём может идти речь?

mihdan
10 лет назад
Ответить на  Ольга Крахмалёва

О какой демо-версии идет речь?

mihdan
10 лет назад
Ответить на  Ольга Крахмалёва

Если вы о сайте ШОС, так его за 6 лет переделали не единожды. Пост от 2009 года)

Предыдущая запись
Следующая запись

Давайте дружить
в Telegram

Авторский блог вашего покорного слуги в Telegram про web, программирование, алгоритмы, инструменты разработчика, WordPress, Joomla, Opencart, Symfony, Laravel, Moonshine, фильмы и сериалы