Purpose of this commit is to avoid html entities in logged message by correctly
managing enclosures. For that purpose a new tool 'nl2br_enclose' is added that
eases Markup management on top of 'nl2br' simple tool.
Task-2710804 (Mail: Clean MailThread Posting API)
Part-of: odoo/odoo#99482
In website(_sale) messages are created from website forms. However those
are technical models, you should always use the MailThread API notably to
ensure values coherency. In our case using message_log seems to be what
original committers wanted to do (even creating a message as a comment
which has no effect as the notification process is not called that way).
Task-2710804 (Mail: Clean MailThread Posting API)
Part-of: odoo/odoo#99482
When overriding an existing controller route, developers can
easily c/p the route definition and call super() in the overridden method
when the route attributes are automatically deducted by odoo from the parent route.
Removing those redefined attributes simplifies the routes definition,
clearly highlighting what's changed by the override.
Also reduces unexpected behavior when modifying the base route without
noticing/considering the redefined attributes in a overridden route,
which overrides the changes made to the base route when the sub-module is installed.
This commit adds a test to catch routes attributes redefinition, and clean existing routes.
closesodoo/odoo#108512
Related: odoo/enterprise#35176
Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
One can very well select a "auth=user route" as homepage for his
website, like /my.
There would then be an issue with such an URL being set as homepage:
- As the user landed in the homepage controller which is auth=public,
the system will add the public user as env user (see
`_auth_method_public()`).
```
@http.route('/', type='http', auth="public", website=True, sitemap=True)
def index(self, **kw):
```
- Then, that controller will reroute to the homepage url (/my). The
request.httprequest.path will now be /my
- Then, that controller will recall the dispatcher stack:
`request._serve_ir_http()`
- From there, this call won't fail as it should because the user is
considered as logged in as it went already through the
`_auth_method_public()`, adding the public user as env.user.
`_auth_method_user()` won't raise its error.
- The /my page will be rendered despite not being logged in.
Once the user land on that page, the system will actually detect him as
logged out on a page supposed to be accessed when logged in.
It will then:
1. Show a toaster to inform the user
2. Auto reload the page
As the current URL is still `/` (due to the reroute and not a redirect),
the same flow will happen again, and again, looping forever.
--------
Note that accessing /my directly won't be an issue, as it won't go
through the homepage controller (which is auth=public), so there won't
be a user_id set on the env (the public user), meaning that the dispatch
layer will reject the access and raise an access error (through
`_auth_method_user()`.
Also note that the same behavior will occur when going through the first
menu fallback mechanism:
- if the user didn't setup any homepage_url
- and deleted his / website.page
- and his first website menu is /my
In that case, it will go through the first menu redirect fallback, which
will be working fine (as it's a redirect and not a reroute).
With both those 2 flows (going through redirect), the user will
correctly land on the login page (which will redirect to /my once logged
in).
------
Finally, the other solution would be to prevent such a configuration
(/my as homepage_url) but it was not easily doable (if doable at all),
see https://github.com/odoo/odoo/pull/99100#discussion_r963055251
------
A test is also added and over the more complexe case (which should cover
everything):
- With /my as homepage_url
- With the / website.page deleted
- With /my as first menu URL
-> Accessing / as public user should:
1. Reroute to /my (because of the homepage_url set to it) which
should fail now thanks to this commit
2. Since the reroute / re-serve failed, it should reach the
"first menu fallback" mechanism, which is also /my
3. That fallback should be a redirect, not a reroute, so the user
should actually land on the login page
4. Once logged in on that page, it should properly redirect to /my
opw-3077339
X-original-commit: 4f5899f769266edc27a0b2d812df092b95f43c71
Part-of: odoo/odoo#107759
Before this commit, following these steps:
- Go to /blog
- Activate the option Customize > Top banner - Name / Latest Post
- Disable the option Customize > Full Width Cover
The URL to which we are redirected when we click on the category of the
post presented at the top of the page leads to an error. In order to fix
the wrong url we had to patch QueryURL so that the url prefix is added
only if the url does not already start with the prefix.
opw-2882492
X-original-commit: https://github.com/odoo/odoo/commit/2b326de107b9b7a2013ee9ff174d81b645d6a623
Part-of: odoo/odoo#104639
*: website_blog, website_event, website_forum, website_slides
With [1] it has been made easier for partners to extend search options.
This task introduces similar inheritable functions for blog posts,
events, forum posts, slides, pages and hybrid results.
[1]: https://github.com/odoo/odoo/commit/d29f2f3ac5f8c3e8109287e0933609bdbe0cadb1
task-2897924
closesodoo/odoo#97908
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
The current implementation of the many2one file upload in website form
will lead to a traceback in case of m2o fields.
It is currently only working with x2many fields. Note that it was
introduced as such with [1].
Step to reproduce:
- install website_sale
- drag & drop form snippet and click on it
- select "create customer" as action option
- add new existing field
- select "Main attachment" and save
- try to submit the form with a file uploaded in that new field
-> Traceback `ValueError: Wrong value for..`
This commit makes it work for all type of relational field.
[1]: https://github.com/odoo/odoo/commit/a77f5cf42faa75a2dd3931d83ad8ea86648248c0closesodoo/odoo#104241
X-original-commit: addea33a8cb6c47bacdbfad0f3082f88763b59ef
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
For the "+New" button, a `get_modules_info` route was added because the
information cannot be built-in the page by a server-side QWeb template
anymore.
This commit removes this route and replaces it by a call to the default
`search_read`.
task-2687506
closesodoo/odoo#102791
X-original-commit: 7f83e398b68d7c7544753e2b8bb1b334fb5f7036
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
This commit improves the design of dynamic products templates.
It introduces templates using multiples rows and fine tunes the
design of the other ones.
To make thumbnails work in the template selector, an extra
data-attribute can now be processed by the snippet option.
- data-thumb: it references the location of the thumbnail for a
template. If present the option will show the svg / img.
If not it will display the name of the template.
task-2677203
Part-of: odoo/odoo#80128
Co-authored-by: Arthur Detroux <ard@odoo.com>
*: website_blog, website_event
Commit [1] introduced new templates. This commit's goal is to build on
that template system to provide more flexibility for designers.
It adds new data-attributes to set on the first node of a template.
- data-row-per-slide: Allows for the template to tell a dynamic snippet
carousel how many rows of cards it should display.
- data-arrow-position: Allows for the template to tell a dynamic snippet
carousel where the arrows should be positioned.
(for now just bottom, or side)
- data-extra-classes: give the template the possibility to add extra
classes to the dynamic snippet instead of just the card.
This commit also removes options to select the amount of elements
displayed on each row. This is now only changeable through templates, or
by directly editing the snippet's DOM through debug tools. This was done
to reduce the amount of options visible, so that the user just chooses
a template and it is ready to go.
[1]: https://github.com/odoo/odoo/commit/49bd79b0bdca76415780bdfa199195371c2692e5
task-2677203
Part-of: odoo/odoo#80128
This commit fixes 2 issues with the position of the dropdown with the
suggested links in the url picker input of the snippet options. (e.g.
redirect url input of the countdown snippet) and the one for the input
of the link editor.
1- Before this commit the dropdown went over the input while editing the
url.
2- Before this commit the position of the dropdown (when above the
input) was a little too low if there were images in the dropdown. It was
because the images are loaded after the positioning of the dropdown and
no height was defined for these images.
task-2900529
closesodoo/odoo#101815
X-original-commit: 774a42ff18651a20b09a5e34222665216b19c8ec
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
The goal of this commit is to:
- Tweak the website filter (on website pages list added at [1]) to make
it work for all website content records (page, blog, ...).
- Update the 'New Page' dialog to be able to select the website_id for
the new page.
- Tweak the '_compute_is_homepage()' method to set 'is_homepage = True'
on website's '/' page when 'homepage_url' is not set in settings.
[1]: https://github.com/odoo/odoo/commit/940f4ee875332dafa1f379970a7683be6b3ee606
task-2889981
X-original-commit: d6014c60acc4231a5e56d492d2a39deaf789cbe8
Part-of: odoo/odoo#101215
*: auth_password_policy, bus, calendar, event, mass_mailing, stock,
survey, web_editor, web_tour, website, website_event, website_forum,
website_mass_mailing, website_sale
This commit is a first step towards a potential deletion of the
assets_common bundle, although that step would need more work, specs and
discussions as some layouts kinda only use the assets_common bundle
(some take the full assets_common but parts of the assets_backend one
for example).
The main goal of this commit is to have the assets_frontend bundle
directly include the "common" files we need. As a first step, this
commit only blindly duplicates them all into assets_frontend (without
removing the potentially useless ones). The goal is to have those
advantages:
- Reaching a frontend page only calls two main JS files (one normal and
one lazy-loaded) instead of 4 (two normals and two lazy-loaded). This
may help reach a better google page speed (which is becoming more and
more strict).
- The frontend CSS is built as one: the common SCSS which was using
bootstrap variables, or even Odoo-based SCSS added by mistake in
common instead of both backend and frontend is now computed with the
right bootstrap customizations. E.g. the tempusdominus datetimepickers
use bootstrap grays... after this PR, they use the right grays as
customized by the user on the website.
It was also chosen to not have a common "sub-asset" which is included in
assets_frontend. Making assets_frontend completely independent makes
sense (as it probably will for other "main" asset bundles): we can focus
on adding the files each layout needs without the need of worrying if it
impacts unrelated layouts. Sub-assets (when not strictly necessary) is
also a source of errors: extending the "main" bundle instead of the
right sub-asset it may use (like it was the case with the sub-assets of
assets_common: _assets_common_scripts and _assets_common_styles as
explained in the previous commit). So this is indeed a small drawback of
not factorizing the code for the inclusion of "common" files in bundles
but it seems more explicit and easier to maintain that way. Note that
adding "common" file is not the most common usecase anyway, apps
generally only need files in backend or frontend.
The __manifest__ declaration will also likely evolve in more and more
uses of wildcards to match entire directories. In the future, adding
"common" web-app files in both backend, frontend and other "main"
bundles could just be about one line duplicated into each bundle.
closesodoo/odoo#100314
Related: odoo/enterprise#31394
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
XML files are now declared in python module manifests. During the qweb
't-call-asset' directive, assetbundle will fetch the declared xml files,
apply the inheritance (t-inherit) and create a javascript service (for
eg: 'web.assets_backend.bundle.xml') which is added at the end of the
*.js mimifier file.
When the debug mode is activated, comments are added in the template
indicating which file the template comes from as well as the
inheritances applied to it.
****
JavaScript:
assets.js (module @web/core/assets) takes care of loading libraries,
javascripts and styles.
`loadJS(url)` (loads the javascript and returns a resolved promise when
the templates are also loaded via the '*.bundle.xml' service)
`loadCSS(url)` (loads the style a resolved promise when the file is
loaded)
`loadXML(xml, app=assets.defaultApp)` (load template into
application/owl, used by the `*.bundle.xml` services)
`getBundle(bundleName)` (get the bundle descriptor)
`loadBundle(desc)` (load the files and bundle from a descriptor)
templates (XML element content all owl templates)
A new `ready(serviceName)` method on boot.js lets you know when a
service is loaded are the require.
The xmlDependencies attribute no longer exists.
Python:
The xmls taken into account by assetbundle.py, applying `t-inherit`
inheritances and adding an `name_of_the_bundle.bundle.xml` service in
the generated JavaScript file.
****
Every manifest changes is into the next commit, except 'web_tour' in
this current commit as example.
Part-of: odoo/odoo#95500
Before this commit, only a website.page could be used as a custom
homepage ('custom' meaning other than '/').
But it is a real use case and requirement for our users to be able to
select a controller as homepage.
For instance, an ecommerce would want its homepage to be the shop and
not a regular page from where you then have to navigate to the shop.
Right now, this can (almost) be achieved by doing some technical
advanced operations:
- Move the 'Shop' menu first in the menu navbar of the website
- Delete the specific '/' website.page for the website
- Delete the generic '/' website.page (no website_id)
That way, the system will redirect `/` to `/shop`, which is not ideal as
it should remain `/` in the URL.
That's because, until now, the homepage (`/` controller) serve order
was:
- Serve the website.page set as homepage (`website.homepage_id`),
happens when one did select another page as homepage through the page
properties dialog
- Serve the website.page having `/` as URL (default)
- Serve the first accessible menu if there no `/` page or other page set
as homepage, it acts as a last resort attempt to not serve a 404 and
to try serving relevant content (the first menu of a website is most
likely always better than a 404)
- Serve 404
This commit allows to introduce an URL as homepage, instead of only a
website.page. It can be done through the website settings in the
backend.
There is 2 main points to keep in mind about serving the homepage:
- make sure we don't serve a 404 as the website homepage. This is the
website entry point, serving a 404 is terrible. That's why we have
some fallback mechanism like serving the first menu.
- We need to serve / before fallbacking to the first menu, as a lot of
site just remove the 'Home' first menu since it is a duplicate of the
logo, which also redirect to the homepage. In such cases, it doesn't
mean that the user want his first menu to be the homepage. We
shouldn't rely on such a behavior, it should just be used as a last
resort.
With this commit, the homepage serve order is now:
- If homepage URL is set (empty by default), serve the website.page
matching it
- If homepage URL is set (empty by default), serve the controller
matching it
- If homepage URL is not set, serve the `/` website.page
- Serve the first accessible menu as last resort. It should be relevant
content, at least better than a 404
- Serve 404
Most DBs will just have a website.page with '/' as URL and keep the
homepage_url setting empty.
task-2969683
closesodoo/odoo#99100
Related: odoo/upgrade#3876
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
lstrip remove each letter, and not only once in this order.
So a google console key like googleeef88156 will be never trusted.
'googleeef88156'.lstrip('google') = 'f88156' and not 'eef88156'
Now we ensure that it starts with google or ends with .html and remove
exactly what we know.
To replace with removeprefix/removesuffix once we have py3.9 as minimal
version.
closesodoo/odoo#99776
X-original-commit: 44c08f18de9b2f25d1c716319ad287a409d2384d
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
Signed-off-by: Jérémy Kersten <jke@odoo.com>
* website_sale_wishlist
When request.website exists, it is supposed to be the same as the
get_current_website() result as that's exactly where it comes from.
The dispatcher, if the request is a frontend one, is setting the
get_current_website() result as the request's website.
closesodoo/odoo#98200
Related: odoo/enterprise#30691
Related: odoo/upgrade#3808
Related: odoo/design-themes#582
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
* portal, web_unsplash, website_*
This commit renames the `website.group_website_publisher` into
`website.group_website_restricted_editor`.
While the change in itself might look unuseful, it will help the dev and
tech community figuring which group is related to which feature.
Even internally when we discuss specs, we always have to remind which
group is the restricted editor: the publisher one or the designer one?
While it is probably, after all those years, now anchored in some dev
mind, there is no easy way to directly figure which of those 2 groups is
the restricted editor one.
Note that I myself always got confused about it.
Now, the "Restricted Editor" right will be reflected in its technical
name `group_website_restricted_editor`.
Same as for the "Editor & Designer" which technical name is
`group_website_designer`.
As we would like to have a fully working and ready system in v17 for the
community to be able to build themes easily, removing that dubious part
is a nice to have.
Part-of: odoo/odoo#98200
Before this commit, the /website/add was always redirecting the requests
to the newly created pages. This way, the controller could be called
from a frontend 404 page (when clicking on the "Create page" button),
and from the WebsitePreview client action's "new content" modal,
introduced in [1].
This commit adds a "redirect" parameter to the controller that will be
used by the 404 page, to keep the same behavior for this use case. But
when called from the webclient, it will return either the id of the
created view (for *.js, *.xml, ... urls), or the new page url, so that
the webclient is not fully reloaded when it is not necessary.
[1]: https://github.com/odoo/odoo/commit/31cc10b91dc7762e23b4bde9b945be0c4ce3fe3b
task-2687506
closesodoo/odoo#97408
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Just a nice to have. It will prevent those errors to be replicated when
copy pasted and will help reading the files in the IDE.
closesodoo/odoo#97282
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
==== Short version ====
Google is deprecating Universal Analytics in July 2023 and Google
Sign-In in March 2023. Google Analytics Embed API is based on Sign-In,
meaning it won't work anymore. It actually already doesn't work anymore
for accounts created somewhere after mid-2020 apparently.
There is no plan for now for Google to allow Analytics 4 dashboard to be
embed in external website.
We therefore can't do anything to keep the Google Analytics dashboard in
Odoo.
In previous stable version, it was kept but is displaying a warning
about it (as until mid 2023 old accounts can still embed it).
All this is about the embed dashboard, not the tracking in itself for
which Odoo is already adapted in Odoo 15.0 for Analytics 4.
==== Detailed version (following short version, read it first) ====
- Universal Analytics EOL July 2023, see [1].
- It will be replaced by Analytics 4 for which Odoo is already ready and
actually using it since version 15.0 with [2].
- Google Sign-In EOL March 2023, see [3]. Analytics Embed API was based
on it, it won't work anymore.
- There is no plan (for now) for Google to allow Analytics 4 to be able
to be embed in external websites. They seem to just have dropped the
"feature".
This was confirmed by Google here [4] and indirectly here [5] in the
DOC:
`Note: This API does not support Google Analytics 4 (GA4) properties`
- While the EOL is planed for 2023, the dashboard integration is already
not working anymore for new accounts.
- Old projects/keys/accounts can still embed their analytics dashboard.
The threshold seems to be somewhere mid-2020, according to [6].
It seems to be accurate as my own key from 2018 still works, while my
keys from 2021 do not.
==== Fix ====
- In stable, warn user about it in their Odoo Analytics dashboard (this
PR) and also add a warning about that on the doc.
- In master, simply drop the whole google analytics dashboard
integration and remove the doc about it, see [7].
==== Useful links ====
[1]: https://support.google.com/analytics/answer/11583528?hl=en
[2]: https://github.com/odoo/odoo/commit/78bc86cbeccfc5df16218aee2b0d7c501e5c05b5
[3]: https://developers.googleblog.com/2022/03/gis-jsweb-authz-migration.html
[4]: https://issuetracker.google.com/issues/233738709?pli=1
[5]: https://developers.google.com/analytics/devguides/reporting/embed/v1
[6]: https://support.google.com/analytics/answer/11583832
[7]: https://www.odoo.com/documentation/15.0/applications/websites/website/optimize/google_analytics_dashboard.html
Finally, note that it means that from July 2023 to Octobre 2023, while
Odoo 14.0 is still supported, Google Analytics won't work anymore in
that version as it will still be designed for Universal Analytics and
not Analytics 4.
opw-2710910
opw-2855405
opw-2881515
opw-2892370
task-2790245
task-2820890
closesodoo/odoo#96280
X-original-commit: d065595f77790fb5ab9480f6de5b88549352324b
Related: odoo/enterprise#29666
Related: odoo/upgrade#3698
Related: odoo/documentation#2499
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
It allows to always have a OdooResponse Object and don't allow redirect
to external except when you allow it explicitly with local=False.
Always return to a local url:
/website/add
/slides/slide/<model("slide.slide"):slide>
/microsoft_outlook/confirm
Allow previously external redirect without reason, now blocked
/website/lang/<lang> -> open redirect
Allow external redirect for good reason and url is controlled by code.
/social_facebook/redirect_to_profile/
PS: HTTP Code 303 is a better default for generic redirects. It's not
historically the default for werkzeug.utils, but it is what we want in
general. Contrary to 302, there is no browser-dependent behavior, and
no risk of asking the user whether they want to accept the redirect if
the original method wasn't GET. It's always a non-permanent GET on the
target location.
closesodoo/odoo#95019
X-original-commit: 77f8d9c5d96a9274785ffc2ad83b95ea157d26ad
Related: odoo/enterprise#29000
Signed-off-by: Olivier Dony <odo@odoo.com>
Signed-off-by: Jérémy Kersten <jke@odoo.com>
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
closesodoo/odoo#94580
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Purpose
=======
When a public user fill a form on Website (e.g. /contactus), an email
will be sent. The email filled in the form will be used as the "email
from", but if no mail server match this email address it will be
encapsulated into "`notifications@mycompany.com`" (see odoo/odoo#61853).
Even though the email is still present in the "Reply-To" header, we
want to add it at the end of the email, so the receiver has this
information easily.
Task-2833093
closesodoo/odoo#94728
X-original-commit: a57944cc387a0b2f0eb6450a14a14e149c720181
Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com>
*: web, web_editor, web_unsplash, website_blog, website_event,
website_forum, website_hr_recruitment, website_links,
website_livechat, website_sale, website_slides, website_twitter
This commit fixes two issues related to the loading the wysiwyg and
editor assets.
The media dialog components are now defined in a new assets_media_dialog
bundle, to make them available both in the frontend (needed to post
comments on the forum for example), and in the backend (used in the
context of the wysiwyg edition or in the seo dialog). Ideally, The media
dialog component would lazy load its own bundle, but right now, it is
not possible when used in a ComponentWrapper.
The wysiwyg assets are now completely loaded in the frontend, after
creating the website root, when the frontend is displayed in an iframe.
It would be better if the frontend loads only what it needs of the
wysiwyg assets (some editor classes and the drop zones css), an
improvement would be to create an assets_wysiwyg_frontend or
assets_wysiwyg_minimal bundle.
The website edition components are moved to the assets_editor bundle.
For now, this bundle is included in the backend and the edition menus
are hidden from the users that are not website publishers. Ideally, the
client action would lazy load the assets_editor, only if the user is a
website publisher.
Many optimizations regarding assets will be done post-merge.
See merge commit for more information.
task-2687506
*: website_blog, website_hr_recruitment, website_sale, website_slides
This commit changes the redirections from the controllers, that were
always redirecting to the frontend before.
Now, we want to open the website in its backend client action most of
the time (for example, when clicking on the "go to website" buttons on
the form views).
For that, a new get_client_action_url is introduced on the website
model.
See merge commit for more information.
task-2687506
The goal of this commit is to add options to manage website pages as in
frontend page manager using list view.
- The click on list view item will redirect iframe to the targeted page.
- The Page Properties dialogs (DuplicatePageDialog, DeletePageDialog)
are used to clone/remove pages.
- The pages listView is loaded using the current website domain.
See merge commit for more information.
task-2687506
Before this commit, the configurator was its own frontend application.
With the website edition UI moved to the backend, it makes also sense to
move the configurator to the backend, as a client action, so that it is
easy to trigger it after installing a website (or the website module),
and returning to the website_preview client action after having
completed it.
This commit adds a new color_palettes.scss file, added in the
assets_backend, that will print the values of the color palettes (so
that some js can handle it). For now, it is needed for the configurator
and the editor. It will probably need to be reviewed later to not put
everything in backend assets.
See merge commit for more information.
task-2687506
On website, the edition is done in an iframe while the SnippetsMenu
resides outside of said iframe. This means that the SnippetsMenu no
longer has frontend styles. Therefore, colors aren't accurate.
This commit aims at patching web_editor widgets, such as color_palette,
so that the color displayed is always accurate. To do so, it computes
the color inside the iframe and adds style attributes to color_palette
preview elements.
See merge commit for more information.
task-2687506
*: mass_mailing, web, web_editor, website_blog, website_event,
website_event_meet, website_livechat, website_sale, website_twitter,
base
This commit does 3 things:
- Adapt existing code so that the editor can be run outside of its
editing element. Prior to this commit, it was expected that the
editor would be attached to the element it was currently editing.
This needs to change however as the editable is now inside an
iframe for the website edition. mass_mailing already had a similar
approach but the editor was started within the iframe.
With these changes, the editor is alongside the iframe, editing
the content that's inside it. This allows multiple features
such as reloading the iframe while keeping the editor visible and
resizing the iframe for a mobile preview.
- Adds logic to the wysiwyg_adapter so that it can undertake
the duty of the previous widget sytem. The wysiwyg existed not only
in the legacy widget system, but most importantly in the frontend.
One of the duties of this adapter is to send events inside the
iframe when it is necessary to reach the frontend public widget
(i.e. widgets_start_request)
- Removes existing SCSS that is no longer used.
See merge commit for more information.
task-2687506
*: website, website_sale_comparison, website_sale_loyalty,
website_sale_slides, website_sale_wishlist
This commit adapts "customize show" options from website sale modules by
creating new options available in edit mode.
See merge commit for more information.
task-2710582
*: website_blog, website_event, website_forum, website_hr_recruitment,
website_livechat, website_sale, website_slides
The NewContentModal component is added. It displays tiles, which will
install a module if not already installed, or perform an action defined
by the module otherwise. So that modules can patch that component to
define an action when installed (for example, website_sale will handle
the logic of creating a new product), the elements to displayed and
their state (NOT_INSTALLED, INSTALLING, INSTALLED) are listed in the
state of the component.
A key 'isDisplayed' is added on the new content elements that should not
be displayed to the user, depended on his security groups.
By default, the new content elements are displayed to the system user.
See merge commit for more information.
task-2687506
This commit adds an underlying iframe, below the main one used to
display the website.
This iframe, used as a fallback inbetween the events 'beforeunload' and
'load' of the main iframe, will host its replicated content to avoid
seeing white flashes.
These white flashes can happen on Chrome Linux and Windows - even on a
regular navigation - but are even more visible in the context of an
iframe.
See merge commit for more information.
task-2687506
No method was readily available to know if a user is `internal` (has
group `base.group_user`), which was inconsistent with other base groups.
_is_internal is now used in the codebase where it is clear that
`.has_group('base.group_user')` is called on a single record.
Part-of: odoo/odoo#85703
Rationnals
----------
Web servers can serve some resources (e.g. static files) right away
without any interaction with the web application. The network model of
most web servers makes them capable of handling thousands of
simultaneous requests when it comes to intensive IO operations such as
streaming data from a file. The network model of Odoo is different: it
is capable of a lot of processing power but can only serve a handful of
requests at a time, i.e. Odoo (with some help from postgres) is
optimized for CPU operations, not IO.
Some users don't configure their web server, they use a basic
configuration that relay all requests to Odoo. The result is that many
Odoo HTTP Workers can be busy streaming static files instead of
processing other requests. This can lead to a worker starvation, i.e.
all workers are busy streaming files and cannot process new requests.
X-Sendfile
----------
In this work, we add the support for the [X-Sendfile] header family,
they are multiples http headers that can be used by the web application
to communicate with the web server in order to delegate the delivery of
files stored on the file system. Odoo still receives the request but it
does no more stream the file content from within its HTTP worker,
instead it skips the response body altogether and sets the `X-Sendfile`
special header with the path of the file on the filesystem. The web
server intercepts that special header, open the file and stream it.
Using those headers, we can use the best of both the web application and
the web server. The web application is still responsible to locate the
resource and verify the access rights, the web server is still
responsible of streaming the content.
Using X-Sendfile is opt-in via the `--x-sendfile` CLI flag. We set both
`X-Sendfile` (apache) and `X-Accel-Redirect` (nginx). If you are using
apache, make sure `mod_xsendfile` is enabled. If you are using NGINX
you have to add the following location block:
location /web/filestore { # custom path, hardcoded within Odoo
# Prevent access from the outside world, i.e. makes this
# route only accessible via X-Accel. MANDATORY!!!
internal;
# Give access to the filestore using this server's
# permissions. Odoo is in charge of verifying the access
# rights.
alias /path/to/odoo/data-dir/filestore;
}
The Odoo [deployment documentation] has been updated accordingly.
[X-Sendfile]: https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/
[deployment documentation]: https://www.odoo.com/documentation/master/administration/install/deploy.html#serving-static-files-and-attachments
Changes to the API
------------------
To benefit most from X-Sendfile, all APIs related to streaming content
over HTTP has to be adapted. They are: (1) `request._serve_static`,
(2) `ir.http._serve_fallback`, (3) `/web/content` and (4) `/web/image`.
Each used it own way to deliver content: (1) `_serve_static` was using
`send_file` (flask's send_file that as been vendored with odoo 10
years ago and not maintenained since then), (2) _serve_fallback was
handcrafting a `werkzeug.wrappers.Response`, (3) /web/content-image were
using the "binary server" `ir.http.binary_content` API.
I has been decided to remove all 3 APIs and to merge the code inside of
the new `http.Stream` object and the `ir.binary` helper model.
A Stream wraps what is going to be sent to the browser, it can be a path
to a file on the locale filesystem, a blob of raw data or an URL to an
external resource. The Stream also holds various metadata that are
mainly used for caching. The preferred way to create a Stream is via one
of its three factories so that all the metadata are set. The factories
are: `from_path`, `from_attachment` and `from_binary_field`. A stream
instance exposes a single method `get_response()` used to create the
corresponding HTTP response object out of the stream.
Inside of `ir.http` were a few methods that were not related to the http
routing and formed what was called the "binary server". All those
methods have been removed and the feature have been refactored inside of
the new `ir.binary` model. The removed methods are:
- `_xmlid_to_obj`
- `_get_record_and_check`
- `_binary_ir_attachment_redirect_content`
- `_binary_record_content`
- `_binary_set_headers`
- `binary_content`
- `_response_by_status`
- `_get_content_common`
- `_content_image`
- `_content_image_get_response`
- `_placeholder_image_get_response`
The new `ir.binary` abstract model exposes the following utilities:
**`_find_record`**
Find an attachment or a record with a binary-field out of an xmlid or
out of a pair record-model/record-id. Check the access rights and the
access token.
**`_get_stream_from`**
Create a Stream from an attachment or a record with a binary-field.
**`_get_image_stream_from`**
Same as `_get_stream_from` but adapted for images. It sets a sensible
ETag on the stream and has image resizing support.
**`_placeholder`**
Get the image placeholder blob.
Testing
-------
It is possible to test the web server configuration using the
`test_http` module. Install the module then run the unittest using the
`webserver` test-tag. By default it attempts to connect to a web-server
running on `http://localhost:80`, you can change this URL by setting the
`WEB_SERVER_URL` environment variable.
odoo-bin -i test_http --stop-after-init
WEB_SERVER_URL='http://localhost:80' odoo-bin --test-tags webserver --stop-after-init
closesodoo/odoo#88134
Task: 2801675
Related: odoo/documentation#2083
Related: odoo/enterprise#26191
Signed-off-by: Julien Castiaux <juc@odoo.com>
This commit add the way to specify the Plausible shared key auth token and
the plausible domain on your website to have the Plausible Dashboard integrated
in your Website > Dashboard > Analytics menu.
Some custom event are already pre-configured as:
Push an event 'Shop' on confirmation on ecommerce (with amount bucket +/- 50)
Push an event 'Lead Generation' on:
'Thank you' page of contactus
Confirmation of subscription for an event
From this way, the end user can just add a goal 'Lead Generation'
or 'Shop' on Plausible to have the Goal values visible.
closesodoo/odoo#91058
Related: odoo/documentation#2007
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
- Show the Odoo version only in debug mode to logged in user, as we do
for the technical module name.
The purpose of this page is to generate some backlinks and improve
(does it really?) the SEO of Odoo.com.
The Odoo version doesn't bring any value and is another way to easily
retrieve DBs based on their version with a simple Google search.
While there is many other ways to do so, let's avoid this one.
- Prior to the introduction of `website.page` and the new page serve
mechanism, there could be template collision when an user would create
a page with the same key/name than the template of this controller.
This is not the case anymore.
We can remove the refresh meta tag.
See [1] and [2].
- The check to see if the template exists is useless, we don't do that
kind of check when rendering a controller, we just assume the view was
not manually deleted by the user.
I guess it was historically useful when people would not want that
/website/info page to be show. But now, there is a clean way to "hide"
this page by simply disabling it in the "Customize" option of the
website in the navbar.
[1]: https://github.com/odoo/odoo/commit/4cfd86edaa27d09f1066dd017bf466b8b30611e5
[2]: https://github.com/odoo/odoo/commit/7f6c669530ed7f9935de6516fadb7283ac00a9e4closesodoo/odoo#91131
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
When the homepage was set to a different page than /, the resulting page
was blank.
The problem is related to a change of the rerouting algorithm, before
the httpocalypse it was re-dispatching the request itself, now it is up
to the called to do so. Here it is what `serve_path` does.
closesodoo/odoo#91034
X-original-commit: b00fefec2a26eb36be8a13cb845ee4f12f87d4eb
Signed-off-by: Julien Castiaux <juc@odoo.com>
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
There were inconsistencies in the calls to `_render`.
* the view context could contain information that misled developers.
Indeed, the context and value of the view are not supposed to be found
in the rendering. Thus by calling `ir.qweb` with the name of the
template, we ensure that there is no unwanted information and in
addition the cache key is that of the name of the template which saves
a query.
* the context used for rendering was modified by a method on
`ir.ui.view`, except this is not information used by this model. There
is now a `_prepare_environment` method residing on `ir.qweb`. This
method allows to modify the value dictionary as well as the context in
which the rendering will be done. This preparation of the data as well
as my security check is done only once per rendering. This also saves
some queries
* Freeze options for rendering were inconsistent. It could be that
options on which rendering depends were not part of the cache key. Thus,
depending on the user who generated the generation of the rendering
function, there was or was not information in the template. For example
for automatic branding. This is no longer possible, because it is the
context that is used. The options serving as a cache key are only
recorded for information (for the profiling system for example). A
simplification of the `ir.qweb.field` models could be made.
The report rendering and call `ir.qweb` instead of `ir.ui.view`.
Part-of: odoo/odoo#85110
Issue
-----
When website is installed, the rendering of template uses a side effect
of the ORM cache (cache shared between sudoed env vs non-sudoed env) and
the fields prefetching feature to work correctly.
The `self.visibility` in (`_handle_visibility`, website/ir_ui_view.py)
is done in sudo mode, then it will fetch all prefetchable fields and put
them in the cache (that will be read in non-sudo mode in the render of
the template). Another example of issue related to this:
https://github.com/odoo/odoo/pull/83341.
Because of this, the fields of mixin `website.seo.metadata` were forced
to be prefetchable (the default for translate is to be not prefetchable
since https://github.com/odoo/odoo/pull/82896), which causes a useless
LEFT JOIN on "ir_translation" in most of business flow.
Fix
---
Remove the `prefetch=True` on mixin fields, and add a extra read to fill
the cache in case of website rendering. It also allows to read these
fields at the same time.
Part-of: odoo/odoo#85220
We can easily avoid a read on the website table when serving the
homepage by simply caching the website.homepage_id value and then
browsing the record (no query needed) instead of reading it on the
website record.
While this code is not really elegant, it seems like a good tradeoff to
gain a query on this particular homepage serve controller, which is the
main entry point of a website and generally the page the more often
served.
task-2774979
X-original-commit: 69b443b85656c895c66a1f83b235f5d1e53727d4
Part-of: odoo/odoo#85456
- Three controllers were actually useless as the relevant public methods
of the web_editor.assets can be called directly via RPC in the related
usecases.
- Review the web_editor.assets model methods organization in the model
declaration.
closesodoo/odoo#85392
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
This commit is the 14th commit of a comprehensive refactor of our HTTP
framework. See odoo/odoo#78857 for complete historic, discussions and
rationnals.
* `request.uid = x` => `request.update_env(user=x)`.
* `request.context = x` => `request.update_env(context=x)`.
* `request.context = dict(request.context, x=y)`
=> `request.update_context(x=y)`.
* `request.cr = None` => `request.cr.close()`.
* `http.mono_db()` => `request.db`.
* `http.dispatch_rpc()` => `service.dispatch_rpc()`.
* `@service.model.check` => `service.model.retrying()`.
* `request.endpoint`
=> `env['ir.http']._match(request.httprequest.path)[0].endpoint`.
* `request.routing_iteration `=> `removed`.
* `request.jsonrequest` => `request.dispatcher.jsonrequest`.
Note that `request.params` is now set much later in the process. If you
are in a situation where you values from the query string or the
http body you can use `request.get_http_params()`.
Note that using the new `request.future_response`, it is possible to
add headers and cookies on the response object before the response
object is initialized. Please note that headers/cookies saved on
the future response will NOT be injected in case of error.
PR: odoo#78857
Task: 2571224
Issue
-----
When website is installed, the rendering of template uses a side effect
of the ORM cache (cache shared between sudoed env vs non-sudoed env) and
the fields prefetching feature to work correctly.
The `self.visibility` in (`_handle_visibility`, website/ir_ui_view.py)
is done in sudo mode, then it will fetch all prefetchable fields and put
them in the cache (that will be read in non-sudo mode in the render of
the template). Another example of issue related to this:
https://github.com/odoo/odoo/pull/83341.
Because of this, the fields of mixin `website.seo.metadata` were forced
to be prefetchable (the default for translate is to be not prefetchable
since https://github.com/odoo/odoo/pull/82896), which causes a useless
LEFT JOIN on "ir_translation" in most of business flow.
Fix
---
Remove the `prefetch=True` on mixin fields, and add a extra read to fill
the cache in case of website rendering. It also allows to read these
fields at the same time.
Part-of: odoo/odoo#83818
The configurator introduced at [1] uses a frontend controller to
display its content. However this results in inconsistent language
translation as the python code uses the users's language but the
localization services uses the frontend's language when on a frontend
page.
Steps to reproduce:
- Create a database with the only language being french
- Install website
- In the configurator, all the pages will be in french except
"Pages and Features"
With this commit, the language for the configurator will always be
the language of the website it's configuring. A test also make sure
that this is the current behavior.
[1]: https://github.com/odoo/odoo/commit/e8a5af2e28a4724f86783746706cb59175f086bf
task-2687416
closesodoo/odoo#84810
X-original-commit: a0f8fdc65566fafe98dab21f5c2dbab9505c3d5c
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
Step to reproduce:
- Create a website form with its action set to 'create a task'
- Set a project for the task to be created in
- Submit the form while logged in as a portal user
Current Behaviour:
- Task is created but the data from fields is not take into account
This lead to the task not being linked to the project and ending as 'Private'
- Due to the changes of sudo in V15, authorized fields are not fetched
and thus cannot be set properly.
Behaviour after PR:
- The data is fetch via the SUPERUSER instead of sudo to ensure correct data
- The fields are correctly set and the task is created
in the corresponding project.
opw-2743065
closesodoo/odoo#84020
X-original-commit: de03ee2198e039e14d0852d2346cb8aaf3885b5b
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
Signed-off-by: Damhaut Florian (flda) <flda@odoo.com>
website{_*}: website, website_blog, website_event, website_forum,
website_sale, website_slides
Since the generic search bar was introduced in [1] all text fields were
truncated in search results.
This caused problems for long URLs which were truncated as well, and
therefore could become invalid.
After this commit URL fields specify `'truncate': False` in their search
detail metadata, which informs the rendering to skip the text truncation
step for that field.
Also added previously missing controller-level tests of the
autocompletion.
Steps to reproduce:
- start odoo with website_forum and demo data
- go to the Help forum
- search for "configure" in the Help forum
- click on the auto-complete suggestion
- => redirected to a 404 page because the URL was shortened
To test the fix on other models, use a long enough name that causes the
problem. E.g.: "This product has such a long name its URL would have
been truncated without the fix contained in this branch".
Note that the problem did not occur on blogs because the URL does not
contain the name, but the same fix was applied for consistency.
[1]: https://github.com/odoo/odoo/commit/7559626c54e34b41e1549e28276a650accec6986
task-2727788
closesodoo/odoo#82621
X-original-commit: 045f741be35e62f5e3a636490c6c1d475b5d78eb
Signed-off-by: Romain Derie (rde) <rde@odoo.com>