import { lang as Lang } from "/helpers/lang.js"
// or if running into errors due to cells running before the import:
// const lang = await import("/helpers/lang.js");
// or if only needing the main lg function:
// import { lg } from "/helpers/lang.js"
= [
languages key: "en", label: "English", locale: "en-US" },
{ key: "fr", label: "Français", locale: "fr-FR" }
{ ; ]
Lang Module Guide
Author: Zach Bogart, Brayden Youngberg
Version: 2.0.1
Overview
The Lang
module provides a set of helper functions to manage translations, template insertions, and string formatting in JavaScript notebooks and apps. It is especially useful for multi-language support and dynamic text replacement.
Installation & Defining Languages
Define available languages with keys, labels, and locales:
Setting Up Translation JSON
Structure your translations as a nested object or external JSON, with language keys for each field:
= new Object({
nbText "hello": {
"en": "hello",
"fr": "Bonjour"
,
}"error": {
"en": "Whoops"
,
}"insert": {
"small": {
"en": "This is an insertion example: :::field:::",
"fr": "Ceci est un exemple d'insertion: :::field:::"
,
}"big": {
"en": "This is an insertion example: :::field::: :::name:::",
"fr": "Ceci est un exemple d'insertion: :::field::: :::name:::"
}
} })
Language Toggle UI (Observable Example)
Create a master toggle to pick the language key (Observable Inputs):
= Inputs.radio(languages, {
viewof language label: "Main language toggle",
format: (d) => d.key,
value: languages.find((x) => x.key === defaultLangKey),
})
A “pretty” toggle with label that changes based on the language:
- NOTE: it is required to do this in a new Input, as there would be a circular definition otherwise
= {
viewof prettyLanguageView return Inputs.bind(
.radio(languages, {
Inputslabel: Lang.getText({en: "Language", fr: "Langue"}, { key: language.key }),
format: (d) => d.label
,
})
viewof language;
) }
Retrieving Translations
Get a translation for the current language:
.getText(nbText.hello, { key: language.key }); Lang
Shorthand Helper
To avoid repeating the language key, use lg
:
= Lang.lg(language.key);
_lang _lang(nbText.hello);
Template Insertion
Replace placeholders in template strings with dynamic values.
Example: Single Insertion
{const template = Lang.getText(nbText.insert.small, { key: language.key });
const items = [{ name: "field", value: "hello world!" }];
return Lang.reduceReplaceTemplateItems(template, items);
}
Example: Multiple Insertions
{const template = Lang.getText(nbText.insert.big, { key: language.key });
const greeting = Lang.getText(nbText.hello, { key: language.key });
const items = [
name: "field", value: greeting },
{ name: "name", value: "Alice" }
{ ;
]return Lang.reduceReplaceTemplateItems(template, items);
}
Custom Placeholder Delimiters
{const customTemplate = "This is a test: >field<";
const result = Lang.reduceReplaceTemplateItems(
,
customTemplatename: "field", value: "hello world!" }],
[{ start: ">", end: "<" }
{ ;
)return result
}
Checking for Missing Translations
Find missing language keys in your text object:
.listLeavesMissingObjectKeys(nbText, ["en", "fr"]);
Lang// Returns an array of paths to missing translations
String Formatting Helpers
.toTitleCase("welcome to my home"); Lang
.toSentenceCase("welcome to my home"); Lang
Advanced: Default Language from URL
Set the default language using a URL parameter (?lang=fr
):
= await Lang.getParamFromList({
queryLanguage name: "lang",
list: languages.map((d) => d.key)
;
})
= queryLanguage ?? "en"; defaultLangKey
API Reference
Function | Description |
---|---|
lg(defaultKey) | Returns a function to fetch text for a default language key. |
getText(textObj, { key }) | Gets text for the specified language key. |
getRegexForNamedInsertion(item, opts) | Returns regex to match placeholders (default: :::item::: ). |
reduceReplaceTemplateItems(...) | Replaces all placeholders in a template with provided values. |
listLeavesMissingObjectKeys(obj, keys) | Lists object leaves missing specified keys. |
getParamFromList({ name, list, ... }) | Returns query parameter value if it exists in a provided list. |
toTitleCase(str) | Converts a string to title case. |
toSentenceCase(str) | Converts a string to sentence case. |
Links: Observable Notebook Example
Happy translating!