Post by mooonwalker » Tue Mar 05, 2019 12:52 am

Hello guys and girls,
I have installed a blank OC 3.0.3.1 with demo data, add second language, enable and fill SEO URLs, enable htacces and it works fine, until I start to switching languages. I open product macbook at address mystore.com/macbook -> than I switch language and the ulr should change to mystore.com/mekbuk (same product, different language) . The URL stay at mystore.com/macbook but the language of the store and the product is changed. Also when I type that url directly into the browser, it didn't show the correct language. Better see for yourself. http://test2.latexvogue.com/ I only set SEO URLs for iPhone and MacBook for now.
So I'm not sure if it is bug, feature or I made something wrong.
Apologies it this was tackled in the past.
Have a great day
Jerry

Newbie

Posts

Joined
Wed Apr 01, 2015 5:16 am

Post by rjcalifornia » Sun Mar 10, 2019 4:50 pm

mooonwalker wrote:
Tue Mar 05, 2019 12:52 am
Hello guys and girls,
I have installed a blank OC 3.0.3.1 with demo data, add second language, enable and fill SEO URLs, enable htacces and it works fine, until I start to switching languages. I open product macbook at address mystore.com/macbook -> than I switch language and the ulr should change to mystore.com/mekbuk (same product, different language) . The URL stay at mystore.com/macbook but the language of the store and the product is changed. Also when I type that url directly into the browser, it didn't show the correct language. Better see for yourself. http://test2.latexvogue.com/ I only set SEO URLs for iPhone and MacBook for now.
So I'm not sure if it is bug, feature or I made something wrong.
Apologies it this was tackled in the past.
Have a great day
Jerry
Well, that's how that SEO extension works. You must use a SEO extension that supports multilingual URL

https://www.opencart.com/index.php?rout ... on_id=2355

Image
A2 Hosting features: Shared Turbo Boost, Managed Warp 1, Unmanaged Hyper 1, and Warp 2 Turbo


Active Member

Posts

Joined
Fri Sep 02, 2011 1:19 pm
Location - Worldwide

Post by letxobnav » Sun Mar 10, 2019 5:34 pm

since 3.0.2.0 this should work, no need for a paid extension.
what do you mean by only use seo url's for iphone and macbook?

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by xxvirusxx » Sun Mar 10, 2019 6:07 pm

I think is a bug from 3.x, because you need to click twice on same language, then SEO keyword will be changed.

@letxobnav
Only for that products he added SEO keyword for both languages.

http://test2.latexvogue.com/macbook
http://test2.latexvogue.com/mekbuk

Upgrade Service | OC 2.3.0.2 PHP 8 | My Custom OC 3.0.3.8 | Buy me a beer


User avatar
Expert Member

Posts

Joined
Tue Jul 17, 2012 10:35 pm
Location - România

Post by letxobnav » Sun Mar 10, 2019 7:30 pm

Ah, then I fixed that myself some time ago, can't remember.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by mooonwalker » Sun Mar 10, 2019 7:59 pm

Yes, exactly like "xxxvirusxx" says, I have to click twice, also as I mention, if you put direct URL, it does not redirect to right language. Look like it takes language from a browser? Or your last visit? I'm not sure.

letxobnav: is there a chance, that you remember what needs to be changed, in order to make this SEO feature work?

In the mean time, I'll have to wait and stick with the 2.X

Thank you guys so much for replies. Have a great day

Newbie

Posts

Joined
Wed Apr 01, 2015 5:16 am

Post by letxobnav » Mon Mar 11, 2019 4:14 am

The problem is that for multi-language SEO url's, the common/language class cannot work as written.
They put the language-code selection in the form but also the redirect link which is the link to the current page.

For non-multilanguage url's that is fine as the urls are the same.

I can use that redirect link solution because I only have 2 languages so I know that the user can only select the language which is not the current one.

So if my current language is english I create the chinese seo url first and put that in the redirect link and visa versa, problem solved.
If you look at the view source of my pages you will see that the redirect seo link is the link for the other language.

That will not work for more than 2 languages as you have no idea which other language the user will select.
So for sites with more than 2 languages this whole concept of putting a hidden redirect link in the form is flawed unless you put hidden redirect links for ALL languages other than the current one in the form like "en-gb-redirect", "fr-redirect", etc and in the function language() (which is called by the form) check the selected language code and redirect to the corresponding link.

Haven't thought about a better solution than that yet though.

I will post the code I have for 2 languages tomorrow.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by letxobnav » Mon Mar 11, 2019 10:09 am

a better solution would be:

save a copy of the $this->request->get array before calling the view with

Code: Select all

$this->session->data['language_redirect_get'] = $this->request->get;
this will retain the get variables which are now lost.

In function language() you would check if that session variable exists

Code: Select all

if (isset($this->session->data['language_redirect_get'] ) )
and with the variables in that array construct the seo url with the language code you get from the form just like you would from the $this->request->get array , unset the session variable $this->session->data['language_redirect_get'] as it is no longer needed and do the redirect.
So no more redirect link in the form, just the language codes.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by letxobnav » Mon Mar 11, 2019 12:04 pm

For 2 language only and you need to know the respective language_id's and the language code.

mine are 1 for english with language code en-gb and 2 for mandarin with language code zh-tw.

in catalog/common/controller/language.php find the function index() and you will add the code marked by "letxobnav: start/end"



// letxobnav: start
//if current language = english (1) (en-gb), the other is chinese (2)
$other_language_id = ($data['code'] == 'en-gb' ? 2 : 1);
// retain current language id
$current_language_id = $this->config->get('config_language_id');
// set target language_id
$this->config->set('config_language_id',$other_language_id);
// letxobnav: end

if (!isset($this->request->get['route'])) {

$data['redirect'] = $this->url->link('common/home');

} else {
$url_data = $this->request->get;

unset($url_data['_route_']);

$route = $url_data['route'];

unset($url_data['route']);

$url = '';

if ($url_data) {
$url = '&' . urldecode(http_build_query($url_data, '', '&'));
}

$data['redirect'] = $this->url->link($route, $url, $this->request->server['HTTPS']);

}
// letxobnav: start
// restore the original language id
$this->config->set('config_language_id',$current_language_id);
// letxobnav: end

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by letxobnav » Mon Mar 11, 2019 9:16 pm

The code I use for multi language seo url language switching.

file: catalog/controller/common/language.php

Code: Select all

<?php
class ControllerCommonLanguage extends Controller {
	public function index() {
		$this->load->language('common/language');
		$data['action'] = $this->url->link('common/language/language', '', $this->request->server['HTTPS']);
		$data['code'] = $this->session->data['language'];
		$this->load->model('localisation/language');
		$data['languages'] = array();
		$results = $this->model_localisation_language->getLanguages();
		foreach ($results as $result) {
			if ($result['status']) {
				$data['languages'][] = array(
					'name' => $result['name'],
					'code' => $result['code']
				);
			}
		}
		// retain current page get info
		$this->session->data['save_get'] = $this->request->get;
		return $this->load->view('common/language', $data);
	}

	public function language() {
		if (isset($this->request->post['code'])) $this->session->data['language'] = $this->request->post['code'];
		// if we have the previous page get info saved
		if (isset($this->session->data['save_get'])) {
			// get the languages
			$this->load->model('localisation/language');
			$languages = $this->model_localisation_language->getLanguages();
			// retain the current language
			$curr_lang = $this->config->get('config_language_id');
			// temporary set the requested language
			$this->config->set('config_language_id',$languages[$code]['language_id']);
			// create the redirect seo url for the requested language based on the saved get variables
			if (!isset($this->session->data['save_get']['route'])) {
				$url_data = $this->session->data['save_get'];
				unset($url_data['_route_']);
				$url = '';
				if ($url_data) {
					$url = '&' . urldecode(http_build_query($url_data, '', '&'));
				}
				$redirect = $this->url->link('common/home', $url, $this->request->server['HTTPS']);
			} else {
				$url_data = $this->session->data['save_get'];
				unset($url_data['_route_']);
				$route = $url_data['route'];
				unset($url_data['route']);
				$url = '';
				if ($url_data) {
					$url = '&' . urldecode(http_build_query($url_data, '', '&'));
				}
				$redirect = $this->url->link($route, $url, $this->request->server['HTTPS']);
			}
			// restore the current language
			$this->config->set('config_language_id',$curr_lang);
			// redirect to the new seo url
			$this->response->redirect($redirect);
		}
	}
}
you can also remove the hidden variable

Code: Select all

<input type="hidden" name="redirect" value="{{ redirect }}" />
in file: catalog/view/theme/default/template/common/language.twig
as it is no longer used.

enjoy.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by letxobnav » Mon Mar 11, 2019 11:10 pm

small correction:

this:

Code: Select all

if (isset($this->request->post['code'])) $this->session->data['language'] = $this->request->post['code'];
should be:

Code: Select all

		if (isset($this->request->post['code'])) {
			$code = $this->request->post['code'];
			$this->session->data['language'] = $code;
		}

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by mooonwalker » Tue Mar 12, 2019 3:52 am

letxobnav> thank you man, this looks very good, but I'll check ii later.... I'm super busy now :( But definitely will check it and post a reply. Thank you so so much

Newbie

Posts

Joined
Wed Apr 01, 2015 5:16 am

Post by thrace » Tue Jun 11, 2019 2:14 pm

Hi, I have the same issue. I have done the code in language.php file from @letxobnav, but the problem still exist... Is there any other option that i can do to fix this?My opencart version is 3.0.3.1
Thank you in advance for the help in this matter!!!

Newbie

Posts

Joined
Tue Apr 09, 2019 2:24 pm

Post by shah87 » Mon Sep 30, 2019 6:52 pm

@letxobnav

This fix doesn't work, i have already tried. Any other solution, please recommend. Its super annoying actually.

Newbie

Posts

Joined
Wed Jul 30, 2014 10:17 pm

Post by drakas » Wed Feb 19, 2020 10:01 pm

letxobnav wrote:
Mon Mar 11, 2019 9:16 pm
The code I use for multi language seo url language switching.

file: catalog/controller/common/language.php

Code: Select all

<?php
class ControllerCommonLanguage extends Controller {
	public function index() {
		$this->load->language('common/language');
		$data['action'] = $this->url->link('common/language/language', '', $this->request->server['HTTPS']);
		$data['code'] = $this->session->data['language'];
		$this->load->model('localisation/language');
		$data['languages'] = array();
		$results = $this->model_localisation_language->getLanguages();
		foreach ($results as $result) {
			if ($result['status']) {
				$data['languages'][] = array(
					'name' => $result['name'],
					'code' => $result['code']
				);
			}
		}
		// retain current page get info
		$this->session->data['save_get'] = $this->request->get;
		return $this->load->view('common/language', $data);
	}

	public function language() {
		if (isset($this->request->post['code'])) $this->session->data['language'] = $this->request->post['code'];
		// if we have the previous page get info saved
		if (isset($this->session->data['save_get'])) {
			// get the languages
			$this->load->model('localisation/language');
			$languages = $this->model_localisation_language->getLanguages();
			// retain the current language
			$curr_lang = $this->config->get('config_language_id');
			// temporary set the requested language
			$this->config->set('config_language_id',$languages[$code]['language_id']);
			// create the redirect seo url for the requested language based on the saved get variables
			if (!isset($this->session->data['save_get']['route'])) {
				$url_data = $this->session->data['save_get'];
				unset($url_data['_route_']);
				$url = '';
				if ($url_data) {
					$url = '&' . urldecode(http_build_query($url_data, '', '&'));
				}
				$redirect = $this->url->link('common/home', $url, $this->request->server['HTTPS']);
			} else {
				$url_data = $this->session->data['save_get'];
				unset($url_data['_route_']);
				$route = $url_data['route'];
				unset($url_data['route']);
				$url = '';
				if ($url_data) {
					$url = '&' . urldecode(http_build_query($url_data, '', '&'));
				}
				$redirect = $this->url->link($route, $url, $this->request->server['HTTPS']);
			}
			// restore the current language
			$this->config->set('config_language_id',$curr_lang);
			// redirect to the new seo url
			$this->response->redirect($redirect);
		}
	}
}
you can also remove the hidden variable

Code: Select all

<input type="hidden" name="redirect" value="{{ redirect }}" />
in file: catalog/view/theme/default/template/common/language.twig
as it is no longer used.

enjoy.
hello, does somebody knows solution with two domains domain.com english content and domain.es - spain?

Newbie

Posts

Joined
Sun Mar 13, 2016 4:14 pm

Post by letxobnav » Wed Feb 19, 2020 11:23 pm

As I have it now.

The original language switch setup was created without multi-lingual SEO urls in mind (as many things in OC).
The language redirect link is constructed in the index function before the new language has been selected which is fine for non-multi-lingual-seo urls as they are the same. For multi-lingual SEO urls we need to construct the redirect url after the new language is selected in the language() function.

in the index() function:
1) we ditch the redirect link in the index function and in the view (hidden field).
2) we save the current GET variables in the session (see explanation below).

In the language() function:
1) we set the language based on the posted new language code.
2) we determine the language_id based on the language code (I do that hardcoded as I only have 2 languages, you may need to consult the languages class).
3) we save the current config language_id.
4) we set the config language_id to the new language_id because the seo url function uses that variable.
5) we construct the new SEO url.
But because we get to the language() function using POST, we lost the original GET variables from the original page and we need those to construct the new url. Therefore we save the GET variables in the session first in the index() function.
So now we use the saved GET variables and the new config language_id to construct the new SEO url and set nit as the redirect.
6) we restore the original config language_id and do the redirect.

so now my functions look like:

Code: Select all

	public function index() {
		$this->load->language('common/language');
		$data['action'] = $this->url->link('common/language/language', '', $this->request->server['HTTPS']);
		$data['code'] = $this->session->data['language'];
		$this->load->model('localisation/language');
		$data['languages'] = array();
		$results = $this->model_localisation_language->getLanguages();
		foreach ($results as $result) {
			if ($result['status']) {
				$data['languages'][] = array(
					'name' => $result['name'],
					'code' => $result['code']
				);
			}
		}
		// save the get variables
		$this->session->data['save_get'] = $this->request->get;
		return $this->load->view('common/language', $data);
	}

Code: Select all

	public function language() {
		$url = '';
		if (isset($this->request->post['code'])) $this->session->data['language'] = $this->request->post['code'];
		if (isset($this->session->data['save_get'])) {
			// hardcoding the language_id from language code
			$xlang_id = ($this->request->post['code'] == 'en-gb' ? 1 : 2);
			// save current config language_id
			$curr_lang = $this->config->get('config_language_id');
			// set the new config language_id
			$this->config->set('config_language_id',$xlang_id);
			// construct the new SEO url for redirection
			if (!isset($this->session->data['save_get']['route'])) {
				$url_data = $this->session->data['save_get'];
				unset($url_data['_route_']);
				if (isset($url_data['path']) && $url_data['path'] == 90) unset($url_data['path']);
				$url = '';
				if ($url_data) $url = '&' . urldecode(http_build_query($url_data, '', '&'));
				$redirect = $this->url->link('common/home', $url, $this->request->server['HTTPS']);
			} else {
				$url_data = $this->session->data['save_get'];
				unset($url_data['_route_']);
				$route = $url_data['route'];
				unset($url_data['route']);
				$url = '';
				if ($url_data) $url = '&' . urldecode(http_build_query($url_data, '', '&'));
				$redirect = $this->url->link($route, $url, $this->request->server['HTTPS']);
			}
			// restore the original config language_id
			$this->config->set('config_language_id',$curr_lang);
			// redirect
			$this->response->redirect($redirect);
		} else {
			$this->response->redirect($this->url->link('common/home', $url, $this->request->server['HTTPS']));
		}
	}

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by tomeda » Thu Jan 07, 2021 11:18 pm

Hi @letxobnav,

Thanks for the great contribution to OC community.

I've created multilanguage stores with different domains for Bulgarian I have domain.bg and for the Dutch store I have domain.de, how can I make your code to work for that scenario?

I'm using this modification to make language to respect store URL

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<modification>
<name>Add Language Switch Links</name>
<code>link-lang-switch</code>
<version>v3.2</version>
<author>ztm</author>
<link>ztm.ee</link>


	<file path="catalog/controller/common/header.php">
		<operation>
			<search ><![CDATA[$data['menu'] = $this->load->controller('common/menu');]]></search>
			<add position="after"><![CDATA[$url_current = "$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
				if ($url_current == 'domain.bg') {
					// force english here
					$this->session->data['language'] = 'bg';
					$this->response->redirect($this->url->link('common/home'));
				}

				if ($url_current == 'domain.de') {
					// force german here
					$this->session->data['language'] = 'de-de';
					$this->response->redirect($this->url->link('common/home'));
				}
			]]>
			</add>
		</operation>
	</file>
</modification>
But how to make the switch of the language to change the domain?

OpenCart SEO Services
http://tomeda.bg


User avatar
New member

Posts

Joined
Thu Mar 19, 2015 4:48 am

Who is online

Users browsing this forum: No registered users and 18 guests