Kentico localization API for a single page application

Francis Venne asked on June 9, 2020 20:01

Hi,

I’m currently working on a multi-language MVC site with Kentico. For a section, I would like to use a React frontend application instead of standard MVC view. This application should consume our APIs based on the Kentico’s APIs. Our objective is to frontload the localization per page.

First idea:

My first idea was to localize the text with the localization and to return a list of values by prefix. But I didn’t find it. For the texts, I tried to use the CMS.Localization.ResourceStringInfoProvider.GetResourceStrings(), but it gave me the Key and not the translation. I could create a second request, but I guess it would be heavy. Also, I’m not quite sure how I could invalidate the cache in this scenario.

Second idea:

I think of an ADO.NET request, but this would bypass the Kentico’s API. The only way to invalidate cache in this case is by time instead of changes, so I’m not a big fan of this solution.

Last idea:

Create a page type “React page”, with a page type “Localization folder” and a page type “localization” in it. This “localization” would contain the fields “key” and “text” for the resource. In this scenario the cache is not an issue, but I was wondering if there is a cleaner way to do what I want.

Is it possible to retrieve that information out of the box with Kentico?

Thanks in advance!

Correct Answer

Dmitry Bastron answered on June 10, 2020 17:55

Yes, you can retrieve those with just one SQL query like this:

var translationsDictionary = ResourceStringInfoProvider.GetResourceStrings()
    .Source(resourceString => resourceString
        .Join<ResourceTranslationInfo>("CMS_ResourceString.StringID", "CMS_ResourceTranslation.TranslationStringID")
        .Join<CultureInfo>("CMS_ResourceTranslation.TranslationCultureID", "CMS_Culture.CultureID"))
    .WhereEquals("CMS_Culture.CultureCode", "en-US") // use your culture code
    .WhereStartsWith("CMS_ResourceString.StringKey", "custom.") // all strings starting with "custom.*"
    .Columns("StringKey, TranslationText")
    .ToDictionary(k => k.GetStringValue("StringKey", String.Empty),
        v => v.GetStringValue("TranslationText", String.Empty));

You can read more about joining tables here. Also, I recommend caching this data with cache dependencies to "cms.resourcestring|all" and "cms.resourcetranslation|all".

1 votesVote for this answer Unmark Correct answer

Recent Answers


Dmitry Bastron answered on June 10, 2020 09:41

Hi Francis,

Yes, it is possible, please have a look at the documentation page here. If I got your request right, all you need is a call to ResHelper.GetString("localization.key")

0 votesVote for this answer Mark as a Correct answer

Francis Venne answered on June 10, 2020 15:33

Thanks for your answer Dmitry!

Is there a way to list all localizations with a certain prefix, or a certain name? Something like ResHelper.GetStrings("Key.Prefix.*", culture) that would return "Key.Prefix.Something", "Key.Prefix.SomethingElse" with the language as a parameter? Otherwise it will be a lot of call for each key.

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.