Provider

A translation provider base class for loading and attaching locale-dependent text sources.

Import
the javascript logo
import { Provider } from "@schukai/monster/source/i18n/provider.mjs";
Source
the git logo
Package
the npm logo
Since
1.13.0

Introduction

Provider is the base contract for making locale-dependent translations available to a document or subtree.

Core Responsibilities

SurfaceWhat it solves
getTranslations(locale)Resolves a Translations object for the requested locale.
assignToElement(locale, element)Links the translations to one DOM subtree so UI code can resolve text from that scope.
Object-link merge behaviourIf the target already has translations attached, the provider merges into the existing registry.

Where It Fits

Use a provider when translations come from a dedicated source such as embedded JSON, a CMS endpoint, a cache layer or a locale-specific API response. Application code then depends on the provider contract instead of on transport details.

Assign Translations To A Document

import { Provider } from "@schukai/monster/source/i18n/provider.mjs";
import { Locale } from "@schukai/monster/source/i18n/locale.mjs";
import { Translations } from "@schukai/monster/source/i18n/translations.mjs";

class DemoProvider extends Provider {
    getTranslations(locale) {
        const translations = new Translations(locale);
        translations.setText("headline", "Bereit");
        translations.setText("copy", "Die Übersetzungen sind jetzt am Element verfügbar.");
        return Promise.resolve(translations);
    }
}

const section = document.getElementById("provider-demo");
const provider = new DemoProvider();

await provider.assignToElement(new Locale("de", "DE"), section);

const translations = await provider.getTranslations(new Locale("de", "DE"));
document.getElementById("provider-headline").textContent = translations.getText("headline");
document.getElementById("provider-copy").textContent = translations.getText("copy");
Open in playground

Merge A Second Translation Payload Into An Already Linked Element

import { Provider } from "@schukai/monster/source/i18n/provider.mjs";
import { Locale } from "@schukai/monster/source/i18n/locale.mjs";
import { getDocumentTranslations, Translations } from "@schukai/monster/source/i18n/translations.mjs";

class MergingProvider extends Provider {
    constructor(mode = "base") {
        super();
        this.mode = mode;
    }

    getTranslations(locale) {
        const translations = new Translations(locale);
        if (this.mode === "base") {
            translations.assignTranslations({
                title: "Base translation",
                copy: "Loaded from the first provider call.",
            });
        } else {
            translations.assignTranslations({
                title: "Merged translation",
                extra: "Second payload merged into the same registry.",
            });
        }
        return Promise.resolve(translations);
    }
}

const element = document.getElementById("provider-merge-demo");
const locale = new Locale("en", "US");

const render = () => {
    const translations = getDocumentTranslations(element);
    document.getElementById("provider-merge-title").textContent = translations.getText("title", "missing");
    document.getElementById("provider-merge-copy").textContent = `${translations.getText("copy", "missing")} ${translations.getText("extra", "")}`.trim();
};

await new MergingProvider("base").assignToElement(locale, element);
render();

document.getElementById("provider-merge-run").addEventListener("click", async () => {
    await new MergingProvider("merge").assignToElement(locale, element);
    render();
});
Open in playground

Attach Translations To A Dedicated Subtree Instead Of The Whole Document

import { Provider } from "@schukai/monster/source/i18n/provider.mjs";
import { Locale } from "@schukai/monster/source/i18n/locale.mjs";
import { getDocumentTranslations, Translations } from "@schukai/monster/source/i18n/translations.mjs";

class ScopedProvider extends Provider {
    constructor(label) {
        super();
        this.label = label;
    }

    getTranslations(locale) {
        const translations = new Translations(locale);
        translations.setText("copy", `Translations are attached only to ${this.label}.`);
        return Promise.resolve(translations);
    }
}

const locale = new Locale("en", "US");
const subtreeA = document.getElementById("provider-subtree-a");
const subtreeB = document.getElementById("provider-subtree-b");

await new ScopedProvider("subtree A").assignToElement(locale, subtreeA);
await new ScopedProvider("subtree B").assignToElement(locale, subtreeB);

document.getElementById("provider-subtree-a-output").textContent = getDocumentTranslations(subtreeA).getText("copy");
document.getElementById("provider-subtree-b-output").textContent = getDocumentTranslations(subtreeB).getText("copy");
Open in playground

Resolve Different Translation Objects For Different Locales

import { Provider } from "@schukai/monster/source/i18n/provider.mjs";
import { Locale } from "@schukai/monster/source/i18n/locale.mjs";
import { Translations } from "@schukai/monster/source/i18n/translations.mjs";

class LocaleProvider extends Provider {
    getTranslations(locale) {
        const translations = new Translations(locale);
        if (locale.toString().startsWith("de")) {
            translations.setText("headline", "Veröffentlichung bereit");
        } else {
            translations.setText("headline", "Release ready");
        }
        return Promise.resolve(translations);
    }
}

const provider = new LocaleProvider();
const output = document.getElementById("provider-locale-output");

const render = async (locale) => {
    const translations = await provider.getTranslations(locale);
    output.textContent = translations.getText("headline");
};

document.getElementById("provider-locale-en").addEventListener("click", () => render(new Locale("en", "US")));
document.getElementById("provider-locale-de").addEventListener("click", () => render(new Locale("de", "DE")));

await render(new Locale("en", "US"));
Open in playground

Exported

Provider, translationsLinkSymbol

Derived from

BaseWithOptions

Options

The Options listed in this section are defined directly within the class. This class is derived from several parent classes. Therefore, it inherits Options from these parent classes. If you cannot find a specific Options in this list, we recommend consulting the documentation of the BaseWithOptions.

Option
Type
Default
Description
-/-

Properties

The Properties listed in this section are defined directly within the class. This class is derived from several parent classes. Therefore, it inherits Properties from these parent classes. If you cannot find a specific Properties in this list, we recommend consulting the documentation of the BaseWithOptions.

Methods

The methods listed in this section are defined directly within the class. This class is derived from several parent classes. Therefore, it inherits methods from these parent classes. If you cannot find a specific method in this list, we recommend consulting the documentation of the BaseWithOptions.

Structural methods

getTranslations(locale)
Parameters
  • locale {locale|string}: locale
Returns
  • {Promise}

Static methods

[instanceSymbol]()3.27.0
Returns
  • {symbol}
This method is called by the instanceof operator.

Other methods

assignToElement(locale,element)
Parameters
  • locale {locale|string}: locale
  • element {htmlelement}: element
Returns
  • {Provider}

Events

This component does not fire any public events. It may fire events that are inherited from its parent classes.

The current width of the area is too small to display the content correctly.