From 8c0db0a174d4427e7e517bcd30d86bd3c4b59e1e Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Fri, 4 Nov 2022 10:23:14 +0000 Subject: [PATCH] [FIX] website: restore the seo_name field cleaning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Part of [1] was lost during the frontend>backend merge [2]. The SEO name field was not "slugified" anymore in JS, it led to 2 issues: - Bad UX, one could type something and it would end up after save with something completely different - 404/crash: as the generated URL in js (based on the seo name value) would not be slugified, it would redirect to that URL, which would not be found as the record URL in python would be slugified. There would be an URL mismatch between the python route and the JS redirect value. This could still somehow happen as the JS and PY slug are not doing the exact same things but at least this will restore what we had before and mitigate the issue. Step to reproduce: - Go to a blog post and open the SEO dialog - In the custom URL input, type "créé" - You will be redirected to `/@/blog/travel-1/créé-1` This will be a 404 page, as the correct URL is now `/@/blog/travel-1/cree-1`. [1]: https://github.com/odoo/odoo/commit/c387ec19b4648ae52bf3210253febd7825745627 [2]: https://github.com/odoo/odoo/commit/31cc10b91dc7762e23b4bde9b945be0c4ce3fe3b X-original-commit: 3c266751c41ab0a96494ccd6cd1a1fff3a6a7058 Part-of: odoo/odoo#105195 --- .../static/src/components/dialog/seo.js | 22 +++++++++++++++++++ .../static/src/components/dialog/seo.xml | 3 ++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/addons/website/static/src/components/dialog/seo.js b/addons/website/static/src/components/dialog/seo.js index f57ced6713c..6b25893e693 100644 --- a/addons/website/static/src/components/dialog/seo.js +++ b/addons/website/static/src/components/dialog/seo.js @@ -280,6 +280,10 @@ class TitleDescription extends Component { }, () => []); } + //-------------------------------------------------------------------------- + // Getters + //-------------------------------------------------------------------------- + get seoNameUrl() { return this.previousSeoName || this.props.seoNameDefault; } @@ -322,6 +326,24 @@ class TitleDescription extends Component { } return false; } + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + * @param {InputEvent} ev + */ + _updateInputValue(ev) { + // `NFKD` as in `http_routing` python `slugify()` + ev.target.value = ev.target.value.trim().normalize('NFKD').toLowerCase() + .replace(/\s+/g, '-') // Replace spaces with - + .replace(/[^\w-]+/g, '') // Remove all non-word chars + .replace(/-$/g, '') // Remove trailing - + .replace(/--+/g, '-'); // Replace multiple - with single - + this.seoContext.seoName = ev.target.value; + } } TitleDescription.template = 'website.TitleDescription'; TitleDescription.props = { diff --git a/addons/website/static/src/components/dialog/seo.xml b/addons/website/static/src/components/dialog/seo.xml index d384512c5d9..4a526e3d087 100644 --- a/addons/website/static/src/components/dialog/seo.xml +++ b/addons/website/static/src/components/dialog/seo.xml @@ -143,7 +143,8 @@
- +