OC 3.0.3.8
I don't know if this is a bug or it just needs some modifications.
I noticed that when I enable Use SEO URLs and give some one a seo link that assigned to language id 2 (not the default langauge) in seo_url table he doesn't see the product with that language and canonical link is the link for the default language and that also make a problem not indexing the url in search engines because the canonical link. I'm wondering why not loading the language_id from the seo_url table !!! . I thought it is just in my store. I installed oc v 3.0.3.2 on local-host the same thing happened.
Can any one give me a code to make the script load the page according to the language_id in seo_url table.
Regards,
It seems working on my local host, does any one have a better idea to optimize the codes? like removing the query and use something built in the script.
I added:
Code: Select all
if (!isset($this->request->cookie['language'])) {
if (isset($this->request->get['_route_'])) {
$result = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE keyword = '" . $_route_ . "' ");
if ($result->num_rows) {
$lng = $result->row['language_id'];
if ($lng == 2) {
$code = 'ar';
}
else {
$code = 'en-gb';
}
}
}
}
Code: Select all
$languages = $this->model_localisation_language->getLanguages();
And to make the browser redirect to the correct seo url after changing the language:
I added this code at the end of the file language.twig
Code: Select all
<script>
if (window.location.href.indexOf("&") === -1){
var redirect = '{{ redirect }}';
var url = decodeURI(window.location);
redirect = decodeURI(redirect);
url = url.replace(/&/g, "&");
redirect = redirect.replace(/&/g, "&");
if(redirect != url){
location.replace(redirect);
}
}
</script>
still,
Code: Select all
$this->request->get['_route_']
product
category
but also
category/product
category/subcategory
category/subcategory/product
etc.
if you do a search in your seo_url table for the _route_ as a keyword, it is unlikely it will find it as keywords there are split in separate keywords for category, subcategory and product.
So you too would have to split it first using
Code: Select all
$parts = explode('/', $this->request->get['_route_']);
Code: Select all
if (isset($this->request->get['_route_'])) {
$parts = explode('/', $this->request->get['_route_']);
if (!empty($parts[0])) $keyword_to_search_for = $parts[0];
}
And that modification you installed to strip parent categories is based on wrong assumptions.
but then you want to do what you want to do irrelevant of what standards already exist so feel free to do as you wish, it is your site.
DISCLAIMER:
You should not modify core files .. if you would like to donate a cup of coffee I will write it in a modification for you.
https://www.youtube.com/watch?v=zXIxDoCRc84
Please see this video that will explain the bugs in open-cart multi language:by mona wrote: ↑Fri Nov 26, 2021 10:53 amyou could use the language of a found url keyword to override the page language, I prefer to still add a language indicator to the url.
still,
contains the entire request route of the seo url likeCode: Select all
$this->request->get['_route_']
product
category
but also
category/product
category/subcategory
category/subcategory/product
etc.
if you do a search in your seo_url table for the _route_ as a keyword, it is unlikely it will find it as keywords there are split in separate keywords for category, subcategory and product.
So you too would have to split it first usingThen use any of the parts as in:Code: Select all
$parts = explode('/', $this->request->get['_route_']);
No clue what you are trying to do to the language.twig fileCode: Select all
if (isset($this->request->get['_route_'])) { $parts = explode('/', $this->request->get['_route_']); if (!empty($parts[0])) $keyword_to_search_for = $parts[0]; }
And that modification you installed to strip parent categories is based on wrong assumptions.
but then you want to do what you want to do irrelevant of what standards already exist so feel free to do as you wish, it is your site.
https://player.vimeo.com/video/650273438?h=a7aa16f942
Read googles recommendations for multi language / multi country sites and pick the one that is most suitable
Default OC does not set language based on the url and there is no language indication for SEO urls nor non-SEO urls.
Search engine indexing will always get the default language regardless of the seo url language.
The language switcher does switch the language but does not switch to the seo url.
You can use a language indication in the url, many times discussed how to do that on this forum, search for it and read the google documentation above to enable an informed decision.
You could use this which simply adds the redirects in the correct language for all enabled languages to the view and uses that when selected.
(these are total file replacements so backup first if you have made changes there!)
Total replacement for 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();
// save current language id
$language_id_save = $this->config->get('config_language_id');
// for each enabled language set the name, code and seo url in that language
foreach ($results as $result) {
if ($result['status']) {
$url = '';
// determine redirect url for language
$this->config->set('config_language_id',$result['language_id']);
$this->session->data['language'] = $result['code'];
if (!isset($this->request->get['route'])) {
$url_data = $this->request->get;
unset($url_data['_route_']);
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->request->get;
unset($url_data['_route_']);
$route = $url_data['route'];
unset($url_data['route']);
if ($url_data) $url = '&' . urldecode(http_build_query($url_data, '', '&'));
$redirect = $this->url->link($route, $url, $this->request->server['HTTPS']);
}
// add the language redirect data to the view interface
$data['languages'][] = array(
'name' => $result['name'],
'code' => $result['code'],
'href' => $redirect
);
}
}
// restore current language id
$this->session->data['language'] = $data['code'];
$this->config->set('config_language_id',$language_id_save);
return $this->load->view('common/language', $data);
}
public function language() {
$this->load->model('localisation/language');
$languages = $this->model_localisation_language->getLanguages();
$url = '';
// do we have a valid code from the language selection
if (isset($this->request->post['code']) && array_key_exists($this->request->post['code'],$languages) && $languages[$this->request->post['code']]['status']) {
// set the requested language
$this->session->data['language'] = $this->request->post['code'];
// use the correct redirect
$this->response->redirect($this->request->post['redirect_'.$this->request->post['code']]);
} else {
// otherwise just go home
$this->response->redirect($this->url->link('common/home', $url, $this->request->server['HTTPS']));
}
}
}
Code: Select all
{% if languages|length > 1 %}
<div class="pull-left">
<form action="{{ action }}" method="post" enctype="multipart/form-data" id="form-language">
<div class="btn-group">
<button class="btn btn-link dropdown-toggle" data-toggle="dropdown">
{% for language in languages %}
{% if language.code == code %}
<img src="catalog/language/{{ language.code }}/{{ language.code }}.png" alt="{{ language.name }}" title="{{ language.name }}"> <span class="hidden-xs hidden-sm hidden-md">{{ language.name }}</span>
{% endif %}
{% endfor %}
<span class="hidden-xs"> <i class="fa fa-caret-down"></i></span></button>
<ul class="dropdown-menu">
{% for language in languages %}
{% if language.code != code %}
<li><button class="btn btn-link btn-block language-select" type="button" name="{{ language.code }}"><img src="catalog/language/{{ language.code }}/{{ language.code }}.png" alt="{{ language.name }}" title="{{ language.name }}" /> {{ language.name }}</button></li>
<input type="hidden" name="redirect_{{ language.code }}" value="{{ language.href }}" />
{% endif %}
{% endfor %}
</ul>
</div>
<input type="hidden" name="code" value="" />
</form>
</div>
{% endif %}
DISCLAIMER:
You should not modify core files .. if you would like to donate a cup of coffee I will write it in a modification for you.
https://www.youtube.com/watch?v=zXIxDoCRc84
I read google recommendations. I think as long each page has a different url and page content, there should be no problem. I don't like the idea of adding a switch to the link, the idea of using seo url is to get rid of & and ? in the links.
I will try the code in startup.php on live store and see the results. Now google has 0 page indexed with the second language. How my store content with the second language will appear for people in search engines.
Regards,
moshair wrote: ↑Fri Nov 26, 2021 9:41 pmThank you by mona , your codes work like magic, I think this fix should be included in the official oc script.
I read google recommendations. I think as long each page has a different url and page content, there should be no problem. I don't like the idea of adding a switch to the link, the idea of using seo url is to get rid of & and ? in the links.
I will try the code in startup.php on live store and see the results. Now google has 0 page indexed with the second language. How my store content with the second language will appear for people in search engines.
Regards,
thank you
If this is now solved please edit your title to include [SOLVED]
DISCLAIMER:
You should not modify core files .. if you would like to donate a cup of coffee I will write it in a modification for you.
https://www.youtube.com/watch?v=zXIxDoCRc84
https://www.opencart.com/index.php?rout ... n_id=42611
It is forever free to use.
Laptop repair specialist in Sofia, Bulgaria.
Maintaining own OC 3 shop for laptop screens
Thanks but your extension didn't work as I want because:ilian359 wrote: ↑Sat Nov 27, 2021 4:09 amI know that I am late, but anyway I am posting my solution:
https://www.opencart.com/index.php?rout ... n_id=42611
It is forever free to use.
Disadvantages and limitations:
- Letters in SEO URLs must be of English alphabet;
You need to optimize the code to deal with utf8 characters.
I used your file to make an extension that do the same as yours but it supports none English letters. I used my code above in startup.php in this extension. You can advice me if it needs tweaks.
Good luck
in catalog/controller/startup/seo_url.php
change:
Code: Select all
foreach ($parts as $part) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE keyword = '" . $this->db->escape($part) . "' AND store_id = '" . (int)$this->config->get('config_store_id') . "'");
Code: Select all
foreach ($parts as $part) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE keyword = '" . $this->db->escape($part) . "' AND store_id = '" . (int)$this->config->get('config_store_id') . "'");
/************ START override the language if request url seo keyword is found but in a different language than the currently set language *************/
if ($query->num_rows == 1) {
if ($query->row['language_id'] != $this->config->get('config_language_id')) {
$language_id = $query->row['language_id'];
// set the language in the requested url language.
$this->config->set('config_language_id', $language_id);
// get the new language code
$lcq = $this->db->query("SELECT code FROM " . DB_PREFIX . "language WHERE language_id = '" . $language_id . "'");
$code = $lcq->row['code'];
// set the session language
$this->session->data['language'] = $code;
// set the cookie language
setcookie(
'language',
$code,
['expires' => time() + 60 * 60 * 24 * 30,
'path' => '/',
'domain' => $this->request->server['HTTP_HOST'],
'samesite' => 'None',
'secure' => true,
'httponly' => true]);
// Overwrite the default language object
$language = new Language($code);
$language->load($code);
$this->registry->set('language', $language);
}
}
/************ END override the language if request url seo keyword is found but in a different language than the currently set language *************/
DISCLAIMER:
You should not modify core files .. if you would like to donate a cup of coffee I will write it in a modification for you.
https://www.youtube.com/watch?v=zXIxDoCRc84
Thank you, I used your code and it is working very good and now there is no need to strip the category name from the product url. Don't worry open-cart doesn't allow using the same keyword, I tried putting the same keyword I got error:by mona wrote: ↑Sat Nov 27, 2021 10:57 pmif you want to set the language based on seo url language you might want to think about doing it like this:
in catalog/controller/startup/seo_url.php
change:to:Code: Select all
foreach ($parts as $part) { $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE keyword = '" . $this->db->escape($part) . "' AND store_id = '" . (int)$this->config->get('config_store_id') . "'");
But again, be aware you can never have the same keyword anywhere across all languages for this to work, with a language indicator in the url you can.Code: Select all
foreach ($parts as $part) { $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE keyword = '" . $this->db->escape($part) . "' AND store_id = '" . (int)$this->config->get('config_store_id') . "'"); /************ START override the language if request url seo keyword is found but in a different language than the currently set language *************/ if ($query->num_rows == 1) { if ($query->row['language_id'] != $this->config->get('config_language_id')) { $language_id = $query->row['language_id']; // set the language in the requested url language. $this->config->set('config_language_id', $language_id); // get the new language code $lcq = $this->db->query("SELECT code FROM " . DB_PREFIX . "language WHERE language_id = '" . $language_id . "'"); $code = $lcq->row['code']; // set the session language $this->session->data['language'] = $code; // set the cookie language setcookie( 'language', $code, ['expires' => time() + 60 * 60 * 24 * 30, 'path' => '/', 'domain' => $this->request->server['HTTP_HOST'], 'samesite' => 'None', 'secure' => true, 'httponly' => true]); // Overwrite the default language object $language = new Language($code); $language->load($code); $this->registry->set('language', $language); } } /************ END override the language if request url seo keyword is found but in a different language than the currently set language *************/
Warning: Please check the form carefully for errors!
SEO URL must be unique!
Regards,
Hi there,moshair wrote: ↑Sat Nov 27, 2021 11:13 pmThank you, I used your code and it is working very good and now there is no need to strip the category name from the product url. Don't worry open-cart doesn't allow using the same keyword, I tried putting the same keyword I got error:by mona wrote: ↑Sat Nov 27, 2021 10:57 pmif you want to set the language based on seo url language you might want to think about doing it like this:
in catalog/controller/startup/seo_url.php
change:to:Code: Select all
foreach ($parts as $part) { $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE keyword = '" . $this->db->escape($part) . "' AND store_id = '" . (int)$this->config->get('config_store_id') . "'");
But again, be aware you can never have the same keyword anywhere across all languages for this to work, with a language indicator in the url you can.Code: Select all
foreach ($parts as $part) { $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE keyword = '" . $this->db->escape($part) . "' AND store_id = '" . (int)$this->config->get('config_store_id') . "'"); /************ START override the language if request url seo keyword is found but in a different language than the currently set language *************/ if ($query->num_rows == 1) { if ($query->row['language_id'] != $this->config->get('config_language_id')) { $language_id = $query->row['language_id']; // set the language in the requested url language. $this->config->set('config_language_id', $language_id); // get the new language code $lcq = $this->db->query("SELECT code FROM " . DB_PREFIX . "language WHERE language_id = '" . $language_id . "'"); $code = $lcq->row['code']; // set the session language $this->session->data['language'] = $code; // set the cookie language setcookie( 'language', $code, ['expires' => time() + 60 * 60 * 24 * 30, 'path' => '/', 'domain' => $this->request->server['HTTP_HOST'], 'samesite' => 'None', 'secure' => true, 'httponly' => true]); // Overwrite the default language object $language = new Language($code); $language->load($code); $this->registry->set('language', $language); } } /************ END override the language if request url seo keyword is found but in a different language than the currently set language *************/
Warning: Please check the form carefully for errors!
SEO URL must be unique!
Regards,
I noticed a problem with this code, when on a product page you try to change the language the website stay on the same language, so if a French user want to see the US version page he can't, the language switch will never work
Users browsing this forum: No registered users and 106 guests