Localizing modules
Overview
Smartstore is an application where different languages can be easily downloaded and activated in the admin area. Over 30 languages are available for download in the backend via Configuration > Regional Settings > Languages. Activated languages are displayed in the frontend as well as in the backend.
Smartstore modules are shipped with localized text resources for English and German by default. The localized values are located as xml files in the modules folder Localization. The naming convention is resources.{CultureCode}.xml, e.g. resources.de-de.xml for German.
Resource files can also be named differently. Below are all the file names that will be searched for, using the target language with the CultureCode de-de as an example.
Specified language and specified region:
resources.de-de.xmlSpecified language and no region:
resources.de.xmlSpecified language and all other region variants:
resources.de-at.xmlresources.de-ch.xmlresources.de-li.xmlresources.de-lu.xml
American english:
resources.en.us.xmlGeneral english:
resources.en.xml
Resource files are simple XML files whose root node is the Language node. This node contains several LocaleResource nodes, which have a unique name and a Value subnode for the value they contain.
<Language Name="Deutsch" IsDefault="true" IsRightToLeft="false">
<LocaleResource Name="MyResource">
<Value>My resource</Value>
</LocaleResource>
...
</Language>When the application starts, each resource file of all installed modules is checked to see if all entries already exist in the database. Resources whose names do not exist in the database are added.
ResourceRootKey & Children
The ResourceRootKey is set in the module.json file and is prepended to each resource in the XML files.
With this ResourceRootKey value, the full name of the resource in the example above would be Plugins.MyOrg.MyModule.MyResource.
If you don't want the ResourceRootKey to be applied, you can use the AppendRootKey attribute to prevent it.
For LocaleResource nodes the use of child nodes is allowed, which in turn can contain their own LocaleResource nodes. The names of the nodes are concatenated. The full name of the resource in the following example results in Plugins.MyOrg.MyModule.MyExtraNamespace.MyResource.
Annotating Models
Of course, if there are settings in a module, they need to be labeled. We have introduced a convention for this. The textual resources associated with a setting should always have the same name as the setting itself. For example, if there is a setting for the value MySetting in a configuration model of a module, the resource for it should be stored as follows:
The localized value is assigned using the annotation of the property with the LocalizedDisplay attribute.
If you now use the smart-label tag with the asp-for attribute in the Razor view of the configuration page, the value My setting is automatically rendered as a label.
The LocalizedDisplay attribute can also be used at the class level. Since the namespace of a model's textual resources is usually the same, it's class can be designed in a cleaner way. The values of the class attribute and the property are concatenated. The full resource name from the following example is Plugins.MyOrg.MyModule.MySetting.
Display Hints
If you want to add a hint to a setting's label, describing it in more detail, use a LocaleResource. Name it the same as the resource for labeling the setting but add the .Hint suffix.
Now, when you hover over the small question mark next to the setting, a hint appears.
Alternatively, you can define the hint explicitly by using the sm-hint attribute in the smart-label tag.
Enumerations
Textual resources for the values of an enumeration are stored a bit differently. They consist of the literal Enums, then the name of the enumeration, followed by the name of the enumeration member (e.g. Enums.MyEnum.Value1).
Let's take the following enumeration:
This would be localized as follows:
And accessed like this:
FriendlyName & Description
A resource file should also contain the localized name of the module and a description that will be displayed in the Module-Manager when the module is installed.
These are composed of the literal Plugins.FriendlyName for the name of the module or Plugins.Description for the description, followed by the system name of the module as specified in module.json.
PageBuilder
If a PageBuilder block is implemented in a module, you must store the label of the block that is displayed in the Pagebuilder according to the following convention.
Permissions
When a module implements its own PermissionProvider, the permission labels must be stored according to the following convention. We'll use this sample PermissionProvider implementation to illustrate.
Self defines the namespace for all permissions used by the module. It also represents the main permission node of the module in the store backend, under which all other permissions are grouped.
Use this code to localize that node.
There is no need to provide resources for common permissions such as read, update, create, and delete. They are resolved automatically, unlike special permissions such as anotherpermission, which are localized as follows:
Shortcut T
In all views, localized resources can be displayed via the T-helper. In a Razor view, the following statement can be used anywhere.
Last updated
Was this helpful?