Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 164 additions & 0 deletions website_sale_dynamic_review_snippet/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
===================================
Website Sale Dynamic Review Snippet
===================================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:d43413aa9ae52f19e0b4b115657a500479b34562b7628473e4cdc7c3007976b2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fe--commerce-lightgray.png?logo=github
:target: https://github.com/OCA/e-commerce/tree/18.0/website_sale_dynamic_review_snippet
:alt: OCA/e-commerce
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/e-commerce-18-0/e-commerce-18-0-website_sale_dynamic_review_snippet
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/e-commerce&target_branch=18.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

| This module provides a new website snippet that aggregates customer
reviews from product templates.
| It allows website administrators to display up to 100 reviews from one
or more products in a single dynamic block, directly within the Odoo
Website Builder.

| The snippet offers configuration options (maximum number of reviews)
and renders reviews with rating stars, reviewer names, comments, and
associated product names (if multiple products are chosen).
| It is designed to be responsive and mobile-friendly, making it easy to
showcase customer feedback on landing pages or promotional sections.

**Table of contents**

.. contents::
:local:

Use Cases / Context
===================

Business Need
-------------

E-commerce websites often want to highlight customer feedback not only
on individual product pages but also in centralized locations such as
landing pages, category pages, or custom marketing sections.

By default, Odoo reviews are tied to specific products and cannot be
easily aggregated or reused elsewhere on the website.

This module addresses this limitation by introducing a snippet that
collects and displays multiple reviews in one place.

For example:

- A landing page showcasing testimonials from the most popular products.

- A category introduction page summarizing customer experiences.

- A homepage section displaying reviews from newly launched products.

Approach
--------

The module extends the existing ``website_sale`` and ``website_rating``
functionality to provide a configurable snippet.

The snippet fetches published reviews across selected products and
displays them with a configurable limit (default 20, maximum 100).

Useful Information
------------------

- **Dependencies:** Relies on ``website_sale`` and ``website_rating``.

- **Compatible modules:** Works well with marketing and promotional
website features such as sliders, banners, or call-to-action snippets.

- **Suggested setups:** Useful in multi-website or multi-company
scenarios where aggregated feedback should be highlighted across
different contexts.

Usage
=====

To use this module:

1. Go to the Website application.

2. Open the Website Builder (Edit → Add Blocks).

3. In the "Products Snippets" section, drag and drop **Customer
Reviews** into your page.

|Insert Snippet|

4. Configure the snippet by adjusting the maximum number of reviews
(default: 20, max: 100) and set two columns option.

|Configure Snippet|

5. Save your changes and publish the page.

The snippet will now display the aggregated reviews with rating
stars, reviewer details, and comments.

|Rendered Snippet|

.. |Insert Snippet| image:: https://raw.githubusercontent.com/OCA/e-commerce/18.0/website_sale_dynamic_review_snippet/static/description/snippet_insert.png
.. |Configure Snippet| image:: https://raw.githubusercontent.com/OCA/e-commerce/18.0/website_sale_dynamic_review_snippet/static/description/snippet_config.png
.. |Rendered Snippet| image:: https://raw.githubusercontent.com/OCA/e-commerce/18.0/website_sale_dynamic_review_snippet/static/description/snippet_render.png

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/e-commerce/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/e-commerce/issues/new?body=module:%20website_sale_dynamic_review_snippet%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* XXP

Contributors
------------

- `XXP <https://xxp-odoo.com>`__:

- Maksim Shurupov
- Mike Lapin

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/e-commerce <https://github.com/OCA/e-commerce/tree/18.0/website_sale_dynamic_review_snippet>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions website_sale_dynamic_review_snippet/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import controllers
31 changes: 31 additions & 0 deletions website_sale_dynamic_review_snippet/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "Website Sale Dynamic Review Snippet",
"version": "18.0.1.0.0",
"category": "Website",
"depends": ["website_sale"],
"summary": (
"Aggregate website users’ reviews from product templates into a single "
"website snippet (configurable, up to 100 records) "
"accessible in the Odoo Website Builder."
),
"author": "XXP, Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/e-commerce",
"data": [
"views/snippets/options.xml",
"views/snippets/s_dynamic_review.xml",
],
"assets": {
"portal.assets_chatter": [
"website_sale_dynamic_review_snippet/static/src/core/*",
"website_sale_dynamic_review_snippet/static/src/components/*",
"website_sale_dynamic_review_snippet/static/src/services/*",
],
"web.assets_frontend": [
"website_sale_dynamic_review_snippet/static/src/boot/boot_service.esm.js",
],
"web.assets_tests": [
"website_sale_dynamic_review_snippet/static/src/tests/*.esm.js"
],
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import main
65 changes: 65 additions & 0 deletions website_sale_dynamic_review_snippet/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from odoo.http import Controller, request, route

from odoo.addons.mail.tools.discuss import Store


class CustomerReview(Controller):
@route(
["/mail/review/messages"],
methods=["POST"],
type="json",
auth="public",
website=True,
)
def mail_review_messages(self, before=None, after=None, limit=30):
domain = [
("model", "=", "product.template"),
("message_type", "=", "comment"),
("rating_value", ">=", 1),
]
result = (
request.env["mail.message"]
.sudo()
._message_fetch(domain, None, before, after, None, limit)
)
messages = result.pop("messages")
messages_vals_list = messages.portal_message_format(
options={"rating_include": True}
)
for vals in messages_vals_list:
record = request.env[vals["model"]].sudo().browse(vals["res_id"])
vals["thread"]["name"] = record.name
vals["website_url"] = record.website_url
return {
**result,
"data": {
"mail.message": messages_vals_list,
},
"messages": Store.many_ids(messages),
}

@route("/portal/review_init", type="json", auth="public", website=True)
def portal_review_init(self, **kwargs):
store = Store()
request.env["res.users"]._init_store_data(store)
if request.env.user.has_group("website.group_website_restricted_editor"):
store.add(request.env.user.partner_id, {"is_user_publisher": True})
products = request.env["product.template"].search([("is_published", "=", True)])
product_obj = request.env["product.template"]
for product in products:
thread = product_obj._get_thread_with_access(product.id, **kwargs)
if thread:
mode = product_obj._get_mail_message_access([product.id], "create")
has_react_access = product_obj._get_thread_with_access(
product.id, mode, **kwargs
)
can_react = has_react_access
store.add(
thread,
{
"can_react": bool(can_react),
"hasReadAccess": thread.sudo(False).has_access("read"),
},
as_thread=True,
)
return store.get_result()
79 changes: 79 additions & 0 deletions website_sale_dynamic_review_snippet/i18n/ru.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * website_sale_dynamic_review_snippet
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-09-11 23:17+0000\n"
"PO-Revision-Date: 2025-09-11 23:17+0000\n"
"Last-Translator: AI Assistant\n"
"Language-Team: Russian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: website_sale_dynamic_review_snippet
#: model_terms:ir.ui.view,arch_db:website_sale_dynamic_review_snippet.s_dynamic_review_options
msgid "100"
msgstr "100"

#. module: website_sale_dynamic_review_snippet
#: model_terms:ir.ui.view,arch_db:website_sale_dynamic_review_snippet.s_dynamic_review_options
msgid "20"
msgstr "20"

#. module: website_sale_dynamic_review_snippet
#: model_terms:ir.ui.view,arch_db:website_sale_dynamic_review_snippet.s_dynamic_review_options
msgid "40"
msgstr "40"

#. module: website_sale_dynamic_review_snippet
#: model_terms:ir.ui.view,arch_db:website_sale_dynamic_review_snippet.s_dynamic_review_options
msgid "60"
msgstr "60"

#. module: website_sale_dynamic_review_snippet
#: model_terms:ir.ui.view,arch_db:website_sale_dynamic_review_snippet.s_dynamic_review_options
msgid "80"
msgstr "80"

#. module: website_sale_dynamic_review_snippet
#: model_terms:ir.ui.view,arch_db:website_sale_dynamic_review_snippet.s_dynamic_review_snippet
msgid "Customer Reviews"
msgstr "Отзывы клиентов"

#. module: website_sale_dynamic_review_snippet
#. odoo-javascript
#: code:addons/website_sale_dynamic_review_snippet/static/src/components/message_review_list.xml:0
msgid "Load More"
msgstr "Загрузить еще"

#. module: website_sale_dynamic_review_snippet
#: model_terms:ir.ui.view,arch_db:website_sale_dynamic_review_snippet.s_dynamic_review_options
msgid "Max Number of Reviews"
msgstr "Максимальное количество отзывов"

#. module: website_sale_dynamic_review_snippet
#. odoo-javascript
#: code:addons/website_sale_dynamic_review_snippet/static/src/components/message_review_list.esm.js:0
msgid "No messages found"
msgstr "Сообщения не найдены"

#. module: website_sale_dynamic_review_snippet
#: model_terms:ir.ui.view,arch_db:website_sale_dynamic_review_snippet.snippets
msgid "Product Reviews Snippet"
msgstr "Сниппет отзывов о товарах"

#. module: website_sale_dynamic_review_snippet
#. odoo-javascript
#: code:addons/website_sale_dynamic_review_snippet/static/src/components/message_review_list.xml:0
msgid "There are no reviews"
msgstr "Отзывов нет"

#. module: website_sale_dynamic_review_snippet
#: model_terms:ir.ui.view,arch_db:website_sale_dynamic_review_snippet.s_dynamic_review_options
msgid "Two Columns"
msgstr "Две колонки"
Loading