You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -298,6 +302,11 @@ function checkReadingTime() {
298
302
}
299
303
adminforth.list.closeThreeDotsDropdown();
300
304
}
305
+
306
+
functionclick() {
307
+
checkReadingTime();
308
+
}
309
+
301
310
</script>
302
311
```
303
312
@@ -312,6 +321,7 @@ npm i text-analyzer
312
321
313
322
> ☝️ Please note that we are using AdminForth [Frontend API](/docs/api/FrontendAPI/interfaces/FrontendAPIInterface/) `adminforth.list.closeThreeDotsDropdown();` to close the dropdown after the item is clicked.
314
323
324
+
>☝️ Please note that the injected component might have an exposed click function as well as a defined click function, which executes the click on component logic.
Copy file name to clipboardExpand all lines: adminforth/documentation/docs/tutorial/07-Plugins/10-i18n.md
+128Lines changed: 128 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,6 +5,8 @@ Main features:
5
5
- Stores all translation strings in your application in a single AdminForth resource. You can set [allowed actions](/docs/tutorial/Customization/limitingAccess/) only to Developers/Translators role if you don't want other users to see/edit the translations.
6
6
- Supports AI completion adapters to help with translations. For example, you can use OpenAI ChatGPT to generate translations. Supports correct pluralization, even for Slavic languages.
7
7
- Supports any number of languages.
8
+
- Supports BCP47 language codes (e.g., `en-GB`, `pt-BR`) for regional language variants.
9
+
- Configurable primary language.
8
10
9
11
10
12
Under the hood it uses vue-i18n library and provides several additional facilities to make the translation process easier.
@@ -46,6 +48,8 @@ model translations {
46
48
47
49
If you want more languages, just add more fields like `uk_string`, `ja_string`, `fr_string`, `es_string` to the model.
48
50
51
+
> 💡 **Tip**: For regional language variants, you can also use BCP47 codes like `en-GB`, `pt-BR`, `fr-CA` and add corresponding fields like `enGB_string`, `ptBR_string`, `frCA_string`. See the [BCP47 Language Code Support](#bcp47-language-code-support) section for more details.
52
+
49
53
Next, add resource for translations:
50
54
51
55
```tstitle='./resources/translations.ts'
@@ -86,6 +90,9 @@ export default {
86
90
// will hel to filter out incomplete translations
87
91
completedFieldName: 'completedLangs',
88
92
93
+
// optional: set primary language (defaults to 'en' if not specified)
94
+
// primaryLanguage: 'fr', // Uncomment to set French as primary language
@@ -205,6 +212,125 @@ You can add translations for each language manually or use Bulk actions to gener
205
212
206
213
For simplicity you can also use filter to get only untranslated strings and complete them one by one (filter name "Fully translated" in the filter).
207
214
215
+
## BCP47 Language Code Support
216
+
217
+
The i18n plugin supports BCP47 language tags, which allow you to specify regional variants of languages. This is particularly useful for applications that need to support different regional dialects or cultural variations.
218
+
219
+
### Supported Language Code Formats
220
+
221
+
- **ISO 639-1 codes**: Basic language codes like `en`, `fr`, `de`, `es`
When using BCP47 codes, make sure your database schema includes fields for each regional variant:
272
+
273
+
```tstitle='./schema.prisma'
274
+
modeltranslations {
275
+
id String @id
276
+
en_string String
277
+
created_at DateTime
278
+
279
+
// Basic language codes
280
+
fr_string String?
281
+
pt_string String?
282
+
283
+
// Regional variants (BCP47)
284
+
enGB_string String? // British English
285
+
enUS_string String? // American English
286
+
ptBR_string String? // Brazilian Portuguese
287
+
frCA_string String? // Canadian French
288
+
289
+
category String
290
+
source String?
291
+
completedLangs String?
292
+
293
+
@@index([en_string, category])
294
+
@@index([category])
295
+
@@index([completedLangs])
296
+
}
297
+
```
298
+
299
+
## Primary Language Configuration
300
+
301
+
The `primaryLanguage` option allows you to set the default language for your application. This is particularly useful when your application's primary language is not English.
302
+
303
+
### How Primary Language Works
304
+
305
+
- **Default Language**: The language shown to users by default
306
+
- **Fallback Chain**: When a translation is missing, the system falls back to: `requestedlanguage` → `primaryLanguage` → `English`
307
+
- **Translation Source**: English (`en_string`) is always used as the source for AI translations, regardless of the primary language setting
@@ -458,6 +584,8 @@ If you don't use params, you can use `tr` without third param:
458
584
}
459
585
```
460
586
587
+
> 🔄 **Fallback Behavior**: The `tr` function automatically handles fallbacks when translations are missing. It follows this chain: `requestedlanguage` → `primaryLanguage` → `English`. This ensures users always see content in a language they can understand, even if specific translations are missing.
588
+
461
589
> 🙅♂️ Temporary limitation: For now all translations strings for backend (adminforth internal and for from custom APIs)
462
590
appear in Translations resource and table only after they are used. So greeting string will appear in the Translations table only after the first request to the API which reaches the `tr` function call.
463
591
> So to collect all translations you should use your app for some time and make sure all strings are used at
Copy file name to clipboardExpand all lines: adminforth/spa/src/afcl/Input.vue
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@
12
12
ref="input"
13
13
v-bind="$attrs"
14
14
:type="type"
15
-
@input="$emit('update:modelValue', type === 'number' ? Number($event.target?.value) : $event.target?.value)"
15
+
@input="$emit('update:modelValue', type === 'number' ? Number(($event.target as HTMLInputElement)?.value) : ($event.target as HTMLInputElement)?.value)"
0 commit comments