+1, non-binding

On 2026/08/28 23:01:23 "Evan Rusackas (ASF)" wrote:
> Hey all,
> 
> Kicking off a new vote on an old SIP, that’s been largely implemented. Happy 
> to see it moving again, and would be stoked to see it merged as Superset is 
> *almost* fully translated nowadays! Let’s dive in...
> 
> SIP-161 ("Translating Superset asset metadata"): 
> https://github.com/apache/superset/issues/32854
> 
> Quick background:
> This SIP got extensive [DISCUSS] treatment on this list and in the issue back 
> in April 2025, and Max and I converged with the community on a minimal-core 
> direction. Namely, a deployment-configurable `TRANSLATION_HOOK` as the only 
> integration point, with Superset core never storing translations itself.
> 
> The original proposer had to step away for funding reasons before we closed 
> the loop with a vote, and the issue sat until @alex-poor (GH handle) picked 
> it back up with a PR that implements this converged direction:
> 
> https://github.com/apache/superset/pull/40679
> 
> *************** DETAILS ***************
> 
> 
> What new things can be translated?
> 
> • Chart names and dashboard titles, automatically — no author action needed.
> • Home-page "Recents" item titles.
> • Anything an author explicitly wraps in a new `{{ i18n('...') }}` Jinja 
> macro inside a templated field (axis labels, native filter names, etc.)
>     • This is opt-in per field, not automatic.
> • Explicitly not covered: the actual chart data/values and localized 
> number/date formatting, which are the same exclusions the original SIP had.
> 
> 
> How are translations maintained and loaded?
> 
> • Superset core stores none of it, that's the design shift from the original 
> proposal.
> • There's one hook:
>     • TRANSLATION_HOOK(text, locale, **context) -> str | None
>     • You implement it in config, and back it with whatever you want — a 
> static dict, an external MT API, gettext `.po` catalogs, or a database table, 
> whatever
>     • A `TRANSLATION_BATCH_HOOK` variant exists for anything where each 
> lookup is a query or network call. Superset prefetches through it wherever it 
> already holds a full collection (a dashboard's charts, the Recents list). 
> That means a 30-chart dashboard costs 1 hook call, not 30, and results are 
> memoized. The one place that still resolves per-row is the list views, since 
> FAB serializes each row independently. The docs tell you to cache your hook 
> if that matters.
>     • There's no export/import built into core; that's on whatever you build 
> behind the hook.
> 
> 
> Effect on our `.pot`/`.po` effort?
> 
> • None on the existing pipeline — UI chrome strings are unaffected, nothing 
> new gets added to Superset's own translatable-string extraction.
> • One of the four reference hooks in the docs *does* show how a deployment 
> could reuse the gettext toolchain (Poedit/Transifex/Weblate) for asset 
> content. But  that’s in a separate catalog domain (e.g. `assets`) so it can't 
> collide with or pollute our existing UI catalogs. Opt-in per deployment, zero 
> impact on Superset’s core.
> 
> 
> Breaking? Nope… fully additive.
> 
> • Feature flag + a multi-language `LANGUAGES` config are both required to 
> activate anything, so virtually every existing single-language install is 
> untouched.
> • New optional config hooks (no-op if undefined), new dump-only REST fields 
> (`localized_name`/`localized_title`, nothing removed or renamed)
> • One new Jinja macro
> • No DB migration.
> • Editing a name always shows/saves the canonical value, the edit workflow 
> doesn't change.
> 
> 
> Summary of what you'd be voting on:
> 
> 
> • A `TRANSLATION_HOOK(text, locale, **context) -> str | None` config hook 
> (plus an optional batch variant for query/API-backed stores), fully pluggable 
> — static map, external MT service, `.po` catalogs, a DB table, whatever a 
> deployment wants.
> • A `{{ i18n('...') }}` Jinja macro for opt-in translation of templated 
> fields.
> • - Gated behind `ENABLE_I18N_ASSET_TRANSLATIONS` + a multi-language 
> `LANGUAGES` config, so single-language deployments (the default) pay zero 
> cost.
> • No new core dependencies, no DB migration, no translations stored in 
> Superset itself. Fully additive REST fields, editing always operates on the 
> canonical name.
> • Automatically covers chart names and dashboard titles; anything else (axis 
> labels, native filter names, etc.) is opt-in via the macro. Search/filtering 
> on translated text is not addressed. Both are known, named gaps relative to 
> the original SIP's ambitions, not oversights.
> 
> 
> Worth flagging from prior discussion / alternatives:
> 
> • The original motivation explicitly called out *axis and metric labels* as 
> things to translate. This PR only auto-covers `slice_name`/`dashboard_title`. 
> Everything else needs manual `{{ i18n() }}` wrapping per field, per org, so 
> it’s a narrower scope
> • "Search/filter by translated text" was an open question in the original SIP 
> and remains unaddressed — list search still matches canonical text only.
> • The SIP's "markup vs. auto-wrap" contention is resolved as a hybrid option 
> (auto for the two title fields, manual macro for everything else)
> • It was doubted that batch retrieval was feasible *through Jinja* but this 
> PR sidesteps that by prefetching outside the macro (dashboard-charts 
> endpoint, Recents), while the macro itself still resolves one string per call 
> site, consistent with rather than disproving the doubt.
> 
> 
> The PR itself has already had thorough review already — worth an additional 
> pass if you want the engineering details
> 
> *************** /END WALL OF DETAILS ***************
> 
> 
> Please vote:
> 
>  [ ] +1 approve
>  [ ] +0 no opinion
>  [ ] -1 disapprove (please say why)
> 
> Vote will stay open for at least 72 hours.
> 
> Evan Rusackas
> Preset, Inc
> PMC, Apache Superset
> Member, ASF
> 

Reply via email to