Commit graph

2 commits

Author SHA1 Message Date
GitHub Copilot
cb32fb6c0d [I18N] website_sale_lazy_loading: add es, ca, eu and gl translations
All 13 terms of the POT, in the four languages, generated with polib from
the POT Odoo exported.

The wording follows what website_sale_aplicoop already says on the same
site, so the two shops do not name the same thing twice: "Cargar más
productos" / "Carrega més productes" / "Produktu gehiago kargatu",
"Produktuak Orrialdeko", and "karga geldoa" for lazy loading. The selection
labels are repeated verbatim inside the field help, so what the settings
page offers and what the help describes read as the same three options.

The two view terms carry markup: the globe icon of the website-specific
hint and the spinner next to the loading message. Both keep their tags and
attributes untouched, and only the human text -- the icon's title, the
message -- is translated. Note that Odoo leaves that globe title in English
in its own es and ca files; here it is translated, as it is the one thing
in that span a visitor can read.

Also moves the POT under i18n/, where Odoo looks for it and where the rest
of the addons keep theirs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 13:06:00 +02:00
GitHub Copilot
a9d6f52ca6 [ADD] website_sale_lazy_loading: load the /shop listing on demand
The shop pages products: every page is a full reload that throws away the
grid the visitor was reading. This appends the next page to the grid
instead, on scroll or on a "Load more products" click, per website.

The controller does not duplicate /shop. The new /shop/lazy_products calls
shop() and renders the cards out of the qcontext it prepared, so search,
categories, attributes, tags, price filter, sort order and pricelists are
supported by construction -- and so are the values other modules add to the
listing, the wishlist state among them. Out of range pages answer empty
rather than the last page again, which portal.pager would otherwise clamp
to and the frontend would append as duplicates.

The product loop of website_sale.products is replaced by a call to a shared
template, so the first page and the appended ones are the same markup: a
ribbon, a price or a button another module adds to products_item shows up
on every card, not only on the ones the initial render produced.

Progressive enhancement throughout: the first page and the pager are still
what the standard controller renders, and the pager is only hidden once the
widget is running. Without JavaScript -- and for crawlers -- the shop is
exactly what it is without this module. The page size is the shop layout's
"Products per page", the value the pager already uses, so there is nothing
to keep in sync.

The frontend takes no decision about what to show: the server sends the
mode, the URL of the listing on screen and each page of cards. It observes
a block below the grid rather than listening to scroll, restarts the public
widgets on the appended cards, and keeps a button as the fallback for a
failed request or a browser without IntersectionObserver.

Tests cover the block rendering per mode, the filters travelling in the
AJAX URL, and the endpoint on a next page, the last page, an out of range
page, a broken page number and an unknown category.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 12:33:09 +02:00