Add Localization Bundle for Client to Kernel

I need to translate some kernel error messages like “This field is required.” etc.

The resources for “de”,“en”,“nl”,“fr” are stored in this package:

@com.mgmtp.a12.kernel\kernel-core-runtime-api-ts\lib\main\js\a12internal\formatdef\error\bundles

Hence, I created my own ErrorLocalizationBundle into japanese.

How can I register this bundle now from my client code, such that the kernel localization can make global use of it?

I tried to do internal import of the package resources and wrap the localization.ts, but internal imports are forbidden by eslint. So I am hoping there is an official way to register new bundles.

This is used for a demonstrator project.

Hi @achim-red-fog, to overwrite Kernel formal error messages for existing locales or to add translations for new locales, you can use the Localization API. You find the corresponding documentation in getA12: go to Documentation > Development > Components > Utils > Localization. For your use case, the chapter Customization > Custom defaultLocalizerFactory Parameters should help: you would have to pass your new translation source while creating the Localizer-instance.
Be aware that the localization library offers some utility methods which could help you in your task.

Thank you so much for the swift response.

I am already using a defaultLocallizerFactory to localize most parts of the application.
However, the Kernel error messages are stored as enums, such as:

RuntimeFormalErrorEnum[RuntimeFormalErrorEnum.PFLICHT_FELD_FEHLER], "This field is required.");

So I understand that I possibly can’t use the LocalizationTree (with keys, values) as I do for other translation.
Is my understanding correct, that i need to implement the custom lookup function?

The documentation says

overriding A12-default translation is achieved by passing a LocalizationTreeMap that contains custom translations for the same keys that localizables created by A12 components use.

However, as the original keys are integer values (the Key above has value int:81). So I am not sure how to implement this.

To provide some context, here is an excerpt of my BasePage function

    const locale = useSelector(LocaleSelectors.locale());
    const dataFormats = defaultDataFormats(locale);
    const conversion = new JPValueConversion(dataFormats);
    const localizer = defaultLocalizerFactory({
        locale,
        conversion,
        dataFormats,
        translationSource: DEFAULT_TRANSLATIONS
    });

    const A11yResource = getA11yResource(locale.language);

    return (
        <SizeContext.Provider value={{ currentSize: breakPoint.size }}>
            <DndProvider
                backend={DragAndDropUtils.DefaultDndBackend}
                options={DragAndDropUtils.DefaultDndBackendOptions}>
                <LocalizerContext.Provider value={{ locale, conversion, dataFormats, localizer }}>
...

I patched the
com.mgmtp.a12.kernel-kernel-core-runtime-api-ts
to include a Japanese ErrorLocalizationBundle and it works :slight_smile:

Hi @achim-red-fog,

From reading the kernel localization code, I’d expect that the key in the localizable should be
“kernel.formalErrors.PFLICHT_FELD_FEHLER” (not an integer) - is that not the case?

(The key should be constructed in kernel in LocalizableUtil#createFormalErrorKeyFromString)

That’s correct. As far as I understand it from the code kernel responds internally with error-numbers which are than mapped to String by Typscript reverse mapping

const key1 = RuntimeFormalErrorEnum.PFLICHT_FELD_FEHLER // integer:81
const key2= RuntimeFormalErrorEnum[83] //String: "PFLICHT_FELD_FEHLER"

Howecer, I could not find a way such that I could replace/extend the used LanguageBundle from the client.

So i have a file with all translations in Japanese:
//index.ts in ./ja subfolder of bundles
set(RuntimeFormalErrorEnum[RuntimeFormalErrorEnum.PFLICHT_FELD_FEHLER], "このフィールドは必須です。");

But there seems to be no way to provide such translation as with the LocalizationTreeMap that I use for the frontend componets like FORMENGINE_RESOURCE_KEYS etc.

As this is used internally by the kernel, i could not find a way to override the existing bundled translations. That’s why I patched the kernel packe to include my japanese transaltion bundle, which configures the enum values as shown above.

Really not sure if this is the smartest/intenend way…

Moin @achim-red-fog,
if you started your project with the Project Template, you can apply the suggestions of @sebastian-nimble-slate by adding the following to the RESOURCE_KEYS in client/src/localization/keys.ts

kernel: {
      formalErrors: {
          PFLICHT_FELD_FEHLER: ""
      }
}

And provide the respective entries in your localized texts under client/src/localization/resources.

client/src/localization/resources/de_DE.ts

import { LocalizationKeyTreeType } from "../keys";

export const de_DE: LocalizationKeyTreeType = {
    application: {
        title: "A12 Tutorial Application",
        header: {
            userinfo: {
                labels: {
                    loggedInAs: "Angemeldet als",
                    logoutButton: "Ausloggen"
                }
            }
        }
    },
    kernel: {
        formalErrors: {
            PFLICHT_FELD_FEHLER: "Test DE"
        }
    },
    error: {
        security: {
            notAuthorized: {
                description: "Sie haben keine Berechtigung diese Operation durchzuführen."
            }
        },
        attachment: {
            invalidType: "Ungültiger MIME-Typ."
        },
        "content-store": {
            content: {
                invalidSize: "Der Attachment-Inhalt überschreitet die zulässige Maximalgröße."
            }
        }
    }
};

For me it then displays the custom required message properly:

:information_source: In case of questions or issues, we can also have a call about it.

Kind regards,
Jan