[IMP] website_sale_aplicoop: accessibility and responsive polish — phase 8
Quantity control layout: changed from wrapping flex to deliberate two-row
grid so the add-to-cart button sits full-width underneath the stepper,
avoiding accidental line breaks and giving the primary action more pulsing
area. Also removed the /Kg suffix's redundant font rules.
Order card delivery row: reordered to badge-then-date (visually centred),
removed the "Delivery" label, and swapped bg-primary to text-bg-primary for
proper contrast on the home-delivery badge (3.13:1 minimum).
Tooltip translations: moved hardcoded static tooltips from data-bs-title
(untranslatable) to title (QWeb-translatable). Handled the edge case of
"Save Cart" and "Back to Cart" which had translations but no model_terms
reference in the POT, causing the merge to discard them — added the view
reference so translations now apply.
Load-from-history page: added accessibility: a visible status message
("Loading your order…"), a <noscript> fallback with link to the group
order, lang and viewport meta tags, and localised strings for all three
languages. Gave the page a minimal inline style block since it does not
inherit the token system (no website.layout).
Translations: 11 new entries (es/eu/ca) for new/reworded UI strings, plus
two code catalogue entries (products found, Close) that needed the
#. odoo-python comment for _() resolution. Documented the silent-failure
pattern in docs/TRANSLATIONS.md: the POT merge, untranslatable attributes,
and missing code comments.
Tests: 246 passing. Pre-commit: clean.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
162ba0b570
commit
5de7573fba
35 changed files with 2181 additions and 2413 deletions
|
|
@ -106,10 +106,51 @@ PEDIR AL USUARIO QUE GENERE EL POT DESDE LA UI DE ODOO
|
|||
docker-compose cp odoo:/tmp/addon_name.pot ./addon_name/i18n/
|
||||
```
|
||||
|
||||
#### El `.pot` no es opcional: Odoo fusiona los `.po` contra él
|
||||
|
||||
El `.pot` es un artefacto **generado** y está en `.gitignore` (`*.pot`), pero no es
|
||||
prescindible: al importar, Odoo fusiona cada `.po` contra el `.pot` del módulo antes
|
||||
de leerlo.
|
||||
|
||||
```python
|
||||
# odoo/tools/translate.py, PoFileReader.__init__
|
||||
if pot_path:
|
||||
self.pofile.merge(polib.pofile(pot_path))
|
||||
```
|
||||
|
||||
`merge()` de polib **sustituye las ocurrencias de cada entrada por las del POT**, y
|
||||
marca como obsoletas las entradas que el POT no tiene (el lector se salta las
|
||||
obsoletas). Consecuencias prácticas:
|
||||
|
||||
- Añadir una ocurrencia `model_terms:ir.ui.view,...` solo al `.po` **no sirve de
|
||||
nada**: el merge la descarta y la traducción nunca llega a la vista.
|
||||
- Una cadena nueva que no esté en el POT se ignora entera, por muy traducida que
|
||||
esté en los tres idiomas.
|
||||
- Por eso, tras mover una cadena a un atributo traducible o añadir una nueva, hay
|
||||
que **regenerar el POT** antes de que la traducción surta efecto.
|
||||
|
||||
⚠️ Al exportar contra una BD **con datos demo**, el POT se lleva los nombres de los
|
||||
registros demo (productos, impuestos, nombres de pedidos). Genera el POT contra una
|
||||
BD limpia.
|
||||
|
||||
### 2. Actualizar Archivos .po Existentes
|
||||
|
||||
no usar msmerge, corrompe el po. Usa polib.
|
||||
|
||||
Al crear entradas con polib hay dos detalles que fallan **en silencio**:
|
||||
|
||||
```python
|
||||
entry = polib.POEntry(
|
||||
msgid="products found",
|
||||
msgstr="produktu aurkitu dira",
|
||||
# 1. Sin `module:` el lector revienta; sin `odoo-python` la cadena se lee
|
||||
# del .po y se descarta acto seguido (ver Troubleshooting).
|
||||
comment="module: website_sale_aplicoop\nodoo-python",
|
||||
# 2. El número de línea es obligatorio en ocurrencias `code:`.
|
||||
occurrences=[("code:addons/website_sale_aplicoop/models/js_translations.py", "0")],
|
||||
)
|
||||
```
|
||||
|
||||
### 3. Traducir Términos Nuevos
|
||||
|
||||
Editar los archivos `.po` y completar las traducciones:
|
||||
|
|
@ -245,6 +286,58 @@ name = fields.Char(string="Name")
|
|||
4. **Usuario con idioma incorrecto**: Verificar preferencias de usuario
|
||||
5. **Cache**: Reiniciar Odoo: `docker-compose restart odoo`
|
||||
|
||||
### La cadena SÍ está traducida en el .po y sigue saliendo en inglés
|
||||
|
||||
Los tres casos siguientes fallan sin dar ningún error, ni en el log ni al importar.
|
||||
|
||||
**a) El atributo no es traducible.** QWeb solo traduce los de esta lista
|
||||
(`odoo/tools/translate.py`, `TRANSLATED_ATTRS`), más sus variantes `t-attf-`:
|
||||
|
||||
```text
|
||||
string help placeholder alt title label data-tooltip confirm
|
||||
aria-label aria-keyshortcuts aria-placeholder aria-roledescription aria-valuetext
|
||||
```
|
||||
|
||||
`data-bs-title` **no está**: un tooltip escrito ahí nunca se traduce. Usa `title`
|
||||
(Bootstrap lo respeta igual) o pasa el texto desde el endpoint i18n. Tampoco están
|
||||
`aria-description` ni `data-bs-*` en general.
|
||||
|
||||
**b) Falta la referencia a la vista en el POT.** Para que una traducción se aplique
|
||||
a una vista, su entrada necesita una ocurrencia
|
||||
`model_terms:ir.ui.view,arch_db:modulo.xmlid` **en el POT** (ver el apartado del
|
||||
merge más arriba). Síntoma típico: dos botones contiguos, uno traducido y el otro
|
||||
no, con las dos cadenas presentes en el `.po`. Se comprueba así:
|
||||
|
||||
```bash
|
||||
grep -B 4 '^msgid "Save Cart"$' addon/i18n/addon.pot # ¿tiene model_terms?
|
||||
```
|
||||
|
||||
**c) Falta el comentario `#. odoo-python`.** Las cadenas de `_()` se leen del `.po`
|
||||
directamente (no de la BD), y `CodeTranslations._load_python_translations` filtra
|
||||
por ese comentario:
|
||||
|
||||
```python
|
||||
def filter_func(row):
|
||||
return row.get('value') and PYTHON_TRANSLATION_COMMENT in row['comments']
|
||||
```
|
||||
|
||||
Sin él la entrada se lee y se descarta. La entrada tiene que quedar así:
|
||||
|
||||
```po
|
||||
#. module: website_sale_aplicoop
|
||||
#. odoo-python
|
||||
#: code:addons/website_sale_aplicoop/models/js_translations.py:0
|
||||
msgid "products found"
|
||||
msgstr "produktu aurkitu dira"
|
||||
```
|
||||
|
||||
Y ojo con el `:0` final: el lector hace `int(line_number)` sobre las ocurrencias
|
||||
`code:`, así que una sin número de línea lanza `ValueError` y **tumba la carga del
|
||||
catálogo entero**, no solo la de esa entrada.
|
||||
|
||||
Estas cadenas se cachean por proceso, así que después de tocarlas hay que
|
||||
reiniciar Odoo (`docker-compose restart odoo`), no basta con `-u`.
|
||||
|
||||
### Caracteres Especiales
|
||||
|
||||
Usar escape correcto en .po:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue