Верх страницы
Время для прочтения: 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;
	}

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

Автор: Кобзарёв Михаил

Русский разработчик с 20-ти летним стажем. Работаю с PHP, ООП, JavaScript, Git, WordPress, Битрикс, Joomla, Drupal, Opencart, DLE, Laravel, Moonshine, SuiteCRM.

Оптимизирую сайты под Google Page Speed, настраиваю импорты для больших магазинов на WooCommerce + WP All Import. Пишу плагины на заказ. Все мои услуги.

Веду блог о разработке, дайджест в телеграмме и в ВК.

Вы всегда можете нанять меня.

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

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

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

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

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

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

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

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

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

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

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

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

max_7548
max_7548
9 лет назад

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Давайте дружить
в Телеграме

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