[IMP] website: use custom URL for website in backend
The website architecture has been refactored for the internal users and admins with [1]. Now, they can access the website in the backend inside the website app. Long story short, the website will be displayed in an iframe in a client action. The URL of the browser will be tweaked to reflect the iframe one instead of the real one (which is something like /web#action=..). It had a few drawbacks: - On page refresh (F5 or browser button), the user would land on the frontend version of the website instead of remaining in the backend. - When the user edited the URL (Like removing `/shop` and typing `/jobs` instead, he would land on the frontend version too. - Impossible to directly go to the backend version of the website. Those are improved with this commit by using a slightly different URL when we are in the backend. A `/@/` will prefix the iframe URL. If logged in, the user will land on the backend. If not, it will simply redirect to the frontend version of the website. [1]: https://github.com/odoo/odoo/commit/31cc10b91dc7762e23b4bde9b945be0c4ce3fe3b task-2687506 closes odoo/odoo#94580 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
@@ -117,6 +117,23 @@ class Website(Home):
|
||||
website._force()
|
||||
return request.redirect(path)
|
||||
|
||||
@http.route(['/@/', '/@/<path:path>'], type='http', auth='public', website=True, sitemap=False, multilang=False)
|
||||
def client_action_redirect(self, path='', **kw):
|
||||
""" Redirect internal users to the backend preview of the requested path
|
||||
URL (client action iframe).
|
||||
Non internal users will be redirected to the regular frontend version of
|
||||
that URL.
|
||||
"""
|
||||
path = '/' + path
|
||||
mode_edit = bool(kw.pop('enable_editor', False))
|
||||
if kw:
|
||||
path += '?' + werkzeug.urls.url_encode(kw)
|
||||
|
||||
if request.env.user._is_internal():
|
||||
path = request.website.get_client_action_url(path, mode_edit)
|
||||
|
||||
return request.redirect(path)
|
||||
|
||||
# ------------------------------------------------------
|
||||
# Login - overwrite of the web login so that regular users are redirected to the backend
|
||||
# while portal users are redirected to the frontend by default
|
||||
|
||||
@@ -184,9 +184,10 @@ export class WebsitePreview extends Component {
|
||||
|
||||
// This replaces the browser url (/web#action=website...) with
|
||||
// the iframe's url (it is clearer for the user).
|
||||
this.currentUrl = this.iframe.el.contentDocument.location.href;
|
||||
const currentUrl = new URL(this.iframe.el.contentDocument.location.href);
|
||||
currentUrl.pathname = `/@${currentUrl.pathname}`;
|
||||
this.currentTitle = this.iframe.el.contentDocument.title;
|
||||
history.replaceState({}, this.currentTitle, this.currentUrl);
|
||||
history.replaceState({}, this.currentTitle, currentUrl.href);
|
||||
this.title.setParts({ action: this.currentTitle });
|
||||
|
||||
this.websiteService.pageDocument = this.iframe.el.contentDocument;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
import json
|
||||
|
||||
from werkzeug.urls import url_encode
|
||||
|
||||
from odoo import tests
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
@@ -44,3 +46,22 @@ class TestControllers(tests.HttpCase):
|
||||
|
||||
matching_pages = set(map(lambda o: o['value'], suggested_links['matching_pages']))
|
||||
self.assertEqual(set(last_modified_values), set(last_5_url_edited) - matching_pages)
|
||||
|
||||
def test_02_client_action_iframe_url(self):
|
||||
base_url = self.base_url()
|
||||
urls = [
|
||||
'/', # Homepage URL (special case)
|
||||
'/contactus', # Regular website.page URL
|
||||
'/website/info', # Controller (!!also testing multi slashes URL!!)
|
||||
'/contactus?name=testing', # Query string URL
|
||||
]
|
||||
for url in urls:
|
||||
resp = self.url_open(f'/@{url}')
|
||||
self.assertEqual(resp.url, base_url + url, "Public user should have landed in the frontend")
|
||||
self.authenticate("admin", "admin")
|
||||
for url in urls:
|
||||
resp = self.url_open(f'/@{url}')
|
||||
backend_params = url_encode(dict(action='website.website_preview', path=url))
|
||||
self.assertEqual(
|
||||
resp.url, f'{base_url}/web#{backend_params}',
|
||||
"Internal user should have landed in the backend")
|
||||
|
||||
Reference in New Issue
Block a user