Skip to main content

Multilingual management

Lagoon centralizes displayed texts in Dico.xml files. Each key is then referenced in the UI or in code, which avoids hard-coded labels.

Location of the Dico.xml files​

ProjectUsage
App.ClientUser interface texts.
App.ServerServer messages, API errors, and notifications.
App.SharedTexts shared between Client, Server, and Shared, for example enums.

Dictionary format​

Dico.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="" id="root">
<xsd:element name="string">
<xsd:complexType>
<xsd:attribute name="key" use="required" type="xsd:string" />
<xsd:attribute id="fr-FR" name="fr" use="required" type="xsd:string" />
<xsd:attribute id="en-US" name="en" use="required" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:schema>

<!-- Sample -->
<string key="lblSampleKey" fr="Traduction en français" en="English translation" />
</root>

In this example, only the fr-FR and en-US cultures are present. You can add new languages by adding the corresponding attributes to the schema and to the entries.

Usage in C#​

MyService.cs
using Lagoon.Helpers;

public class MyService
{
public string GetTranslatedContent()
{
// Translates the key into the current culture.
return "lblSampleKey".Translate();
}
}

Usage in markup​

Most Lagoon components automatically translate values prefixed with #.

MyComponent.razor
@inherits LgComponentBase

<LgLabel Text="#lblSampleKey" />
<LgButton Text="#save" OnClick="SaveAsync" />
MyComponent.razor.cs
public partial class MyComponent : LgComponentBase
{
private Task SaveAsync(ActionEventArgs args)
{
// Deliberately minimal example: the actual action depends on the page.
return Task.CompletedTask;
}
}

If a component does not directly handle the # prefix, use manual translation.

MyComponent.razor
@inherits LgComponentBase

<LgLabel Text='@("lblSampleKey".Translate())' />

Formatting with Translate()​

Translate() supports string.Format placeholder zones.

Dico.xml
<string key="lblWelcomeUser" fr="Bienvenue {0} ! Dernière connexion le {1}" en="Welcome {0}! Last login on {1}" />
MyService.cs
public string GetWelcomeMessage(string userName, string lastLoginDate)
{
// Injects the values into placeholders {0} and {1} of the dictionary entry.
return "lblWelcomeUser".Translate(userName, lastLoginDate);
}
Line breaks

To display multiline text, you can store \r\n or &#x0a; in the dictionary and apply a white-space: pre-wrap style to the element that displays the text.

Overriding Lagoon keys​

Lagoon components also use dictionary keys. An application can override an existing key by declaring the same key in its own Dico.xml.

Hot loading on the client side​

A component inheriting from LgComponentBase can load or override translations at runtime with App.LoadLanguages(...).

MyComponent.razor.cs
public partial class MyComponent : LgComponentBase
{
public void LoadLanguage()
{
Dictionary<string, Dictionary<string, string>> dicoToLoad = new();

Dictionary<string, string> fr = new();
Dictionary<string, string> en = new();

fr.Add("lblSampleKey", "La traduction en français");
en.Add("lblSampleKey", "English translation");

dicoToLoad.Add("fr", fr);
dicoToLoad.Add("en", en);

// Loads the translations and refreshes the components using the dictionary.
App.LoadLanguages(dicoToLoad);
}
}

A key defined in Dico.xml is overridden by App.LoadLanguages(...). If the key does not exist, it is added.

Hot loading on the server side​

On the server side, dynamic loading is done through the Lagoon application manager.

LanguageService.cs
public class LanguageService
{
public void LoadLanguages(Dictionary<string, Dictionary<string, string>> dico)
{
// Loads translations server-side for translated API responses.
LgApplicationBase.Current.LoadLanguages(dico);
}
}

Client / server synchronization​

No specific action is required to synchronize the language between the UI and the APIs: when the client changes language, subsequent requests receive server responses in the same language when Translate() is used server-side.

Useful characters in XML​

SequenceResult
&amp;amp;&
&amp;lt;<
&amp;gt;>
&#x0a;Line break
&#8226;Black bullet

See also​