Skip to content

Commit e41e568

Browse files
committed
feat: add locale dropdown selector for nav link translations
1 parent d9af136 commit e41e568

3 files changed

Lines changed: 65 additions & 48 deletions

File tree

javascripts/discourse/initializers/init-nav-bar-additions.js

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,24 @@
11
import { withPluginApi } from "discourse/lib/plugin-api";
2-
import { i18n } from "discourse-i18n";
3-
import { themePrefix } from "virtual:theme";
2+
import I18n from "I18n";
43

54
/**
6-
* Resolve a localized field for a nav link.
7-
*
8-
* Priority:
9-
* 1. Theme translations (locales/*.yml via i18n/themePrefix) — for default
10-
* links that have keys defined in locale files.
11-
* 2. Settings translations (nested translations objects) — for custom links
12-
* where admins add per-locale overrides inside the settings editor.
13-
* 3. Raw settings value — the base display_name/title from the link.
5+
* Resolve a field value from a nav link, checking for a locale-specific
6+
* translation first. Falls back to the base field value.
147
*/
158
function getLocalizedField(link, fieldName) {
16-
// 1. Try theme translations (locale files)
17-
const key = link.display_name.replace(/\s+/g, "_").toLowerCase();
18-
const translationKey = themePrefix(`nav_links.${key}.${fieldName}`);
19-
const themeTranslated = i18n(translationKey);
20-
21-
if (themeTranslated !== translationKey) {
22-
return themeTranslated;
23-
}
24-
25-
// 2. Try settings translations (nested objects)
269
const translations = link.translations;
27-
if (translations && translations.length > 0) {
28-
const locale = i18n.currentLocale?.() || i18n.locale || "";
10+
if (!translations || translations.length === 0) {
11+
return link[fieldName];
12+
}
2913

30-
// Exact match first (e.g. "pt_BR"), then prefix match (e.g. "pt")
31-
const match =
32-
translations.find((t) => t.locale === locale) ||
33-
translations.find((t) => locale.startsWith(t.locale));
14+
const locale = I18n.currentLocale();
3415

35-
if (match && match[fieldName]) {
36-
return match[fieldName];
37-
}
38-
}
16+
// Try exact match first (e.g. "pt_BR"), then prefix match (e.g. "pt")
17+
const match =
18+
translations.find((t) => t.locale === locale) ||
19+
translations.find((t) => locale.startsWith(t.locale));
3920

40-
// 3. Fallback to raw settings value
41-
return link[fieldName];
21+
return (match && match[fieldName]) || link[fieldName];
4222
}
4323

4424
// Built-in Discourse filter routes that have associated topic counts

locales/en.yml

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,11 @@ en:
1919
description: Per-language overrides for display name and title
2020
properties:
2121
locale:
22-
label: Language code
23-
description: "Locale code (e.g. fr, de, zh_CN, pt_BR)"
22+
label: Language
23+
description: Select the language for this translation
2424
display_name:
2525
label: Display name
2626
description: Translated display name for this language
2727
title:
2828
label: Title
2929
description: Translated title (hover text) for this language
30-
nav_links:
31-
latest:
32-
display_name: Latest
33-
title: topics with recent posts
34-
categories:
35-
display_name: Categories
36-
title: all topics grouped by category
37-
top:
38-
display_name: Top
39-
title: the most active topics in the last year, month, week or day

settings.yml

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,58 @@ nav_links:
3939
identifier: locale
4040
properties:
4141
locale:
42-
type: string
42+
type: enum
4343
required: true
44-
validations:
45-
min_length: 2
46-
max_length: 10
44+
choices:
45+
- ar
46+
- be
47+
- bg
48+
- bs_BA
49+
- ca
50+
- cs
51+
- da
52+
- de
53+
- el
54+
- en
55+
- en_GB
56+
- es
57+
- et
58+
- fa_IR
59+
- fi
60+
- fr
61+
- gl
62+
- he
63+
- hr
64+
- hu
65+
- hy
66+
- id
67+
- it
68+
- ja
69+
- ko
70+
- lt
71+
- lv
72+
- nb_NO
73+
- nl
74+
- pl_PL
75+
- pt
76+
- pt_BR
77+
- ro
78+
- ru
79+
- sk
80+
- sl
81+
- sq
82+
- sr
83+
- sv
84+
- sw
85+
- te
86+
- th
87+
- tr_TR
88+
- ug
89+
- uk
90+
- ur
91+
- vi
92+
- zh_CN
93+
- zh_TW
4794
display_name:
4895
type: string
4996
validations:

0 commit comments

Comments
 (0)