На одном из проектов на OpenCart попалась проблема с мультиязычностью. На сайте используется два языка, украинский (как основной) и русский. Страницы основного языка индексируются нормально и отдают ответ 200, а урлы на русском (/ru/… ) идут с редиректом 301 на основной язык. Тоесть они выпадают с индекса.
На сайте так же установлен переключатель языков. Если переключатель на украинском языке, то все страницы этого языка нормально отображаются и не перенаправляются. Если переключатель на русском языке, то все страницы этого языка также нормально отображаются и не перенаправляются (нет редиректа 301). Но если переключатель языка находится на одном из языков, к примеру на украинском, то если я добавляю в урл код языка (/ru/) то идет редирект на тот язык на котором стоит переключатель, тоесть текущий язык забит в сессии и при смене в урле языка, все-равно идет переход на язык в сессии.
Решение проблемы из других источников
Покопавшись в способах решения проблемы, в интернете, нашел что некоторые люди решают это вводя новую переменную get[‘lng’] и в .htaccess создают запись по отправке этой переменной скрипту catalog/controller/startup/startup.php. Далее в зависимости какое значение переменной, переключать язык на нужный. Лично мне этот способ не подошел так как возникли некоторые баги.
Мой вариант решение проблемы переключения языка по урлу
Просмотрев внимательно код сайта, нашел что есть модуль seo_pro.php, в котором как раз и реализовано переключение языка по урлу.
Модуль находился тут
catalog\controller\common\seo_pro.php
Код самого переключения языка по урлу
public function index() { $code = null; // If language specified in URI - switch to code from URI if(isset($this->request->get['_route_'])) { $route_ = $this->request->get['_route_']; $tokens = explode('/', $this->request->get['_route_']); if(array_key_exists($tokens[0], $this->languages)) { $code = $tokens[0]; $this->request->get['_route_'] = substr($this->request->get['_route_'], strlen($code) + 1); } if(trim($this->request->get['_route_']) == '' || trim($this->request->get['_route_']) == 'index.php') { unset($this->request->get['_route_']); } } if(isset($this->request->get['original_route'])) { unset($this->request->get['original_route']); } // Detect language code if(!isset($code)) { if (isset($this->session->data['language'])) { $code = $this->session->data['language']; } elseif (isset($this->request->cookie['language'])) { $code = $this->request->cookie['language']; } else { $code = $this->config_language; } } if(!isset($this->session->data['language']) || $this->session->data['language'] != $code) { $this->session->data['language'] = $code; } . . . }
В коде написано что берется переменная get[‘_route_’] и из неё выделяется код языка, если код языка не определен то берется из сессии, кукиса, конфига, и назначается сессии
$this->session->data['language'] = $code;
Прикол в том, что на сайте оказалось два модуля seo_pro.php
catalog/controller/common/seo_pro.php
catalog/controller/startup/seo_pro.php
И как раз первый не работал, а подключен был из startup.
Во втором модуле, код переключения изменили и он фактически не работал. Тоесть разработчики SeoPro уже позаботились о таком переключении и не надо изобретать велосипед, но разработчики сайта думали по другому )
И тут возникает дилема, есть два кода переключения языка:
- — код переключения языка по select box
- — код переключения языка по урлу
и один другому мешает, надо их совместить.
Код переключения языка по select находится тут
catalog\controller\common\language.php
public function language() { if (isset($this->request->post['code'])) { $this->session->data['language'] = $this->request->post['code']; } if (isset($this->request->post['redirect'])) { $this->response->redirect($this->request->post['redirect']); } else { $this->response->redirect($this->url->link('common/home')); } }
Я сделал так, ввел новую переменную в сессии (маркер для select)
в файле language.php
public function language() { if (isset($this->request->post['code'])) { $this->session->data['language'] = $this->request->post['code']; $this->session->data['lang_select'] = true; }
и перенес код переключения языка в файл startup.php, так как он срабатывает перед выполнением seo_pro.php
catalog/controller/startup/startup.php
изменив некоторые строчки
if(empty($code)) { $code = $this->config_language; // если код не определен } // установка кода в сессию и кукис if(isset($this->session->data['lang_select'])){ unset($this->session->data['lang_select']); }else{ if(!isset($this->session->data['language']) || $this->session->data['language'] != $code) { $this->session->data['language'] = $code; $this->request->cookie['language'] = $code; } }