summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRomain Derie <rde@odoo.com>2021-04-19 16:18:30 +0000
committerRomain Derie <rde@odoo.com>2021-04-27 09:49:34 +0000
commit733411fe03b924832d6b10cadf93c8fc09cc5802 (patch)
treedd6d45be0e00857fb3c3dd07f20435b3ff1796a8
parent8d452ae16b7e6c3077d9eae135852bada43cec93 (diff)
[FIX] website: use correct url code to get canonical url
Before this commit, we would compare a lang `code` (used in context) and a lang `url_code`. For languages where those 2 are differents, the `if` condition would always be falsy, making the canonical URL impossible to be reached. Technically, this condition is used to get the translated name of records to later construct the canonical URL. Since the canonical URL will be incorrect and unreachable, the whole system to tell search engine/crawler about translation won't work since no `alternate/hreflang`[1] will be set in the DOM. [1] see https://developers.google.com/search/docs/advanced/crawling/localized-versions -------- Technical explanation: - italian language `code` = `it_IT`, `url_code` = `it` - belgian french language `code` = `fr_BE`, `url_code` = `fr_BE` Install those languages on website as secondary languages. Translate blog `Travel` to `Voyager` in french and `Viaggi` in italian. Visiting `/fr_BE/blog/travel-1/post/post-1` will redirect to `/fr_BE/blog/voyager-1/post/post-1` as it should, and the canonical URL will be set to that same URL. Visiting `/it/blog/travel-1/post/post-1` will redirect to `/it/blog/voyager-1/post/post-1` as it should, but the canonical URL will be set to `/it/blog/travel-1/post/post-1`. opw-2486918 closes odoo/odoo#69867 X-original-commit: 413357e0f4538ad441184d1d8b4c9a49fc18a5d9 Signed-off-by: Romain Derie <rdeodoo@users.noreply.github.com>
-rw-r--r--addons/test_website/controllers/main.py4
-rw-r--r--addons/test_website/tests/test_is_multilang.py45
-rw-r--r--addons/website/models/website.py2
3 files changed, 50 insertions, 1 deletions
diff --git a/addons/test_website/controllers/main.py b/addons/test_website/controllers/main.py
index f36053cd38f..63333b8157e 100644
--- a/addons/test_website/controllers/main.py
+++ b/addons/test_website/controllers/main.py
@@ -44,6 +44,10 @@ class WebsiteTest(Home):
def test_company_context(self):
return request.make_response(json.dumps(request.context.get('allowed_company_ids')))
+ @http.route('/test_lang_url/<model("res.country"):country>', type='http', auth='public', website=True, sitemap=False)
+ def test_lang_url(self, **kwargs):
+ return request.render('test_website.test_view')
+
# Test Session
@http.route('/test_get_dbname', type='json', auth='public', website=True, sitemap=False)
diff --git a/addons/test_website/tests/test_is_multilang.py b/addons/test_website/tests/test_is_multilang.py
index 69259f32054..1c7d61801e1 100644
--- a/addons/test_website/tests/test_is_multilang.py
+++ b/addons/test_website/tests/test_is_multilang.py
@@ -24,3 +24,48 @@ class TestIsMultiLang(odoo.tests.HttpCase):
self.assertEqual(fr_prefix + '/post', body.find('./form[@id="post"]').get('action'))
self.assertEqual(fr_prefix + '/get_post', body.find('./a[@id="get_post"]').get('href'))
self.assertEqual('/get_post_nomultilang', body.find('./a[@id="get_post_nomultilang"]').get('href'))
+
+ def test_02_url_lang_code_underscore(self):
+ website = self.env['website'].browse(1)
+ it = self.env.ref('base.lang_it').sudo()
+ en = self.env.ref('base.lang_en').sudo()
+ be = self.env.ref('base.lang_fr_BE').sudo()
+ country1 = self.env['res.country'].create({'name': "My Super Country"})
+
+ it.active = True
+ be.active = True
+ website.domain = 'http://127.0.0.1:8069' # for _is_canonical_url
+ website.default_lang_id = en
+ website.language_ids = en + it + be
+ params = {
+ 'src': country1.name,
+ 'value': country1.name + ' Italia',
+ 'type': 'model',
+ 'name': 'res.country,name',
+ 'res_id': country1.id,
+ 'lang': it.code,
+ 'state': 'translated',
+ }
+ self.env['ir.translation'].create(params)
+ params.update({
+ 'value': country1.name + ' Belgium',
+ 'lang': be.code,
+ })
+ self.env['ir.translation'].create(params)
+ r = self.url_open('/test_lang_url/%s' % country1.id)
+ self.assertEqual(r.status_code, 200)
+ self.assertTrue(r.url.endswith('/test_lang_url/my-super-country-%s' % country1.id))
+
+ r = self.url_open('/%s/test_lang_url/%s' % (it.url_code, country1.id))
+ self.assertEqual(r.status_code, 200)
+ self.assertTrue(r.url.endswith('/%s/test_lang_url/my-super-country-italia-%s' % (it.url_code, country1.id)))
+
+ body = lxml.html.fromstring(r.content)
+ # Note: this test is indirectly testing the `ref=canonical` tag is correctly set,
+ # as it is required in order for `rel=alternate` tags to be inserted in the DOM
+ it_href = body.find('./head/link[@rel="alternate"][@hreflang="it"]').get('href')
+ fr_href = body.find('./head/link[@rel="alternate"][@hreflang="fr"]').get('href')
+ en_href = body.find('./head/link[@rel="alternate"][@hreflang="en"]').get('href')
+ self.assertTrue(it_href.endswith('/%s/test_lang_url/my-super-country-italia-%s' % (it.url_code, country1.id)))
+ self.assertTrue(fr_href.endswith('/%s/test_lang_url/my-super-country-belgium-%s' % (be.url_code, country1.id)))
+ self.assertTrue(en_href.endswith('/test_lang_url/my-super-country-%s' % country1.id))
diff --git a/addons/website/models/website.py b/addons/website/models/website.py
index abf54ff5129..9a87b1ccef8 100644
--- a/addons/website/models/website.py
+++ b/addons/website/models/website.py
@@ -971,7 +971,7 @@ class Website(models.Model):
for key, val in list(arguments.items()):
if isinstance(val, models.BaseModel):
if val.env.context.get('lang') != lang.code:
- arguments[key] = val.with_context(lang=lang.url_code)
+ arguments[key] = val.with_context(lang=lang.code)
path = router.build(request.endpoint, arguments)
else:
# The build method returns a quoted URL so convert in this case for consistency.