Files
computer-playbook/plugins/lookup/i18n_content.py
T
kevinveenbirkenbachandClaude Opus 5 f1161f33d0 feat(dashboard): serve the role descriptions and menu in every translated language
port-ui reads per-language content catalogs from i18n/content/<code>.yaml,
mapping each English text to its translation. The new i18n_content lookup
builds them from the core catalogs for every message whose msgctxt starts
with role: or menu:, for each language that translates at least one of
them. The role renders one file per language through
render_replicated_templates, so swarm peers carry the same catalogs, and
mounts the directory at /app/i18n/content.

The German Playwright test compares / with /de/ and expects at least one
translated card description and one translated menu category. Its expected
cards are the deployed roles (group_names) rather than
roles_with_service('dashboard'): the minimal variant switches the dashboard
flag off on the apps, which emptied the expectation while the page still
showed their cards.

to_nice_yaml already passes allow_unicode=True to yaml.dump; passing it
again raised "got multiple values for keyword argument 'allow_unicode'".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 18:53:21 +02:00

35 lines
1.1 KiB
Python

from __future__ import annotations
from pathlib import Path
from typing import Any
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
from utils.i18n.keyed import source_keyed_catalogues
class LookupModule(LookupBase):
"""
Usage:
{{ lookup('i18n_content', 'role:', 'menu:') }}
Returns ``{code: {english: translation}}`` built from the ``core``
gettext catalogs for every message whose ``msgctxt`` starts with one of
the given prefixes, for every language that translates at least one.
A term may also be a list of prefixes.
"""
def run(self, terms, variables: dict[str, Any] | None = None, **kwargs):
if not terms:
raise AnsibleError(
"lookup('i18n_content', prefix, ...) expects at least 1 term"
)
root = Path(str((variables or {})["playbook_dir"]))
prefixes = tuple(
str(prefix)
for term in terms
for prefix in (term if isinstance(term, list) else [term])
)
return [source_keyed_catalogues(root, prefixes)]