Skip to content

Commit

Permalink
[mts-template] investigate localization possibilities of blazor appli…
Browse files Browse the repository at this point in the history
…cation (#133)

* Create draft PR for #132

* Add resx files

* Icon changes to nav menu

* Templarte localization

* Security localization

* Documentation to localization

---------

Co-authored-by: TimothyBucka <TimothyBucka@users.noreply.github.com>
Co-authored-by: TimothyBucka <timotej.bucka@gmail.com>
Co-authored-by: Brano5 <97288158+Brano5@users.noreply.github.com>
  • Loading branch information
4 people authored Jul 26, 2023
1 parent 66e7a6c commit c475844
Show file tree
Hide file tree
Showing 45 changed files with 2,756 additions and 691 deletions.
91 changes: 91 additions & 0 deletions docfx/articles/localization/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# **Template localization**

Localization is a useful feature of any application. It allows you to translate the application into different languages. This guide will show you how localization is achieved in our template Blazor application - `templates.simple`.

## Prerequisites

- _Microsoft.Extensions.Localization_ NuGet package

## Localization in Blazor

To make use of localization in Blazor, make sure that:

- Localization services are added in `Program.cs`:

```csharp
builder.Services.AddLocalization();
```

- Localization middleware with supported languages is added in the correct order to the middleware pipeline in `Program.cs`:

```csharp
var supportedCultures = new[] { "en-US", "sk-SK", "es-ES"};
var localizationOptions = new RequestLocalizationOptions()
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);
```

- In `_Imports.razor` the following `@using` directives are added:

```csharp
@using System.Globalization
@using Microsoft.Extensions.Localization
```

For more information on localization in Blazor visit [Microsoft Docs](https://learn.microsoft.com/en-us/aspnet/core/blazor/globalization-localization).
## Adding support for a new language

In order to add a new language support to the application, a resource file (_.resx_) needs to be created. Resource file are in the forefront of localization in .NET. They are used to store app data (in our case strings), that can be easily accessed and changed without recompiling the app.

In our template application, resource files are located in the `Resources` folder. Create a new resource file for the language you want to add. The name of the file should be in the following format: `ResourceName.culture.resx`, where `culture` is the culture code of the language. E.g. `ResourceName.de.resx` would be a resource file for German language.

If you want to make resource files easier to work with, check out [ResXManager](https://marketplace.visualstudio.com/items?itemName=TomEnglert.ResXManager) extension for Visual Studio.
In `_Imports.razor` make sure that the `@using` directive for the newly created resource file is added and inject the `IStringLocalizer` service of the resource file. E.g.:

```csharp
@using axosimple.hmi.Resources

@inject IStringLocalizer<ResourceName> Localizer
```

## Changing the language dynamically

To change the language dynamically, add a new `CultureInfo` object to the `supportedCultures` array in the code section of `Index.razor`. E.g.:

```csharp
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("sk-SK"),
new CultureInfo("es-ES"),
new CultureInfo("de-DE") // newly added language
};
```

When selecting a language from the `<select>` menu in `Index.razor`, a **cookie** with selected language is created by `ChangeCulture` method of `CultureController`.

## Using localized strings

To use localized strings, simply use `Localizer` service previously injected in `_Imports.razor` E.g.:

```csharp
<h1>@Localizer["Hello World!"]</h1>
```

If the string is not found in the resource file, the key is returned instead. If it is found, however, the localized string is returned.

English:

![Hello_english](~/images/hello_english.png)

Slovak:

![Ahoj_slovak](~/images/ahoj_slovak.png)

Spanish:

![Hola_spanish](~/images/hola_spanish.png)
19 changes: 10 additions & 9 deletions docfx/articles/themes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,14 @@ Compile these files in the following order using the `sass` compiler:

## 3. Using a theme

The custom compiled bootstrap files are stored in the `wwwroot\css\custom` folder. To use a new theme, an `<option>` element needs to be added to the `<select>` element in the `Index.razor` file:
The custom compiled bootstrap files are stored in the `wwwroot\css\custom` folder. Add your custom compiled bootstrap to this folder. In order to be able to switch to your newly created theme, you need to add the name of the theme to the `supportedThemes` array in the `Index.razor` file:

```html
<select class="form-control" @bind="Theme" @bind:event="oninput">
<option value="bootstrap" selected="@(CurrentTheme == "bootstrap")">Bootstrap default</option>
<option value="new_theme" selected="@(CurrentTheme == "new_theme")">New Theme</option>
</select>
```csharp
private string[] supportedThemes = new[]
{
"New Theme",
"Bootstrap",
};
```

Upon selecting a new theme, redirection to the `theme` uri is triggered:
Expand All @@ -158,10 +159,10 @@ In the `_Host.cshtml` file, the `css` file of the selected theme is loaded based
```html
@switch (Request.Cookies["theme"])
{
case "new_theme":
case "New Theme":
<link rel="stylesheet" href="~/css/custom/new_theme.css" />
break;
case "bootstrap":
case "Bootstrap":
<link rel="stylesheet" href="~/css/custom/bootstrap_default_custom.css" />
break;
default:
Expand All @@ -170,7 +171,7 @@ In the `_Host.cshtml` file, the `css` file of the selected theme is loaded based
}
```

Make sure that the `value` attribute of the `<option>` element in the `Index.razor` file matches with the correct `case` string in the `switch` statement in the `_Host.cshtml` file. In case of an unknown theme name from the `theme` cookie or when the app is opened for the first time (the cookie has not been created yet), the default bootstrap theme is loaded.
Make sure that the string name of your theme in `supportedThemes` array in `Index.razor` file matches with the correct `case` string in the `switch` statement in the `_Host.cshtml` file. In case of an unknown theme name from the `theme` cookie or when the app is opened for the first time (the cookie has not been created yet), the default bootstrap theme is loaded.

Theme changes in action:

Expand Down
3 changes: 3 additions & 0 deletions docfx/articles/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,6 @@
href: ~/articles/security/INSTALLATION.md
- name: Template themes
href: ~/articles/themes/README.md
- name: Template localization
href: ~/articles/localization/README.md

File renamed without changes
Binary file added docfx/images/ahoj_slovak.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docfx/images/hello_english.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docfx/images/hola_spanish.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/api/AXOpen.Data.DataExchangeView.html
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ <h5 class="overrides">Overrides</h5>
<a href="https://github.com/ix-ax/AXOpen/new/dev/apiSpec/new?filename=AXOpen_Data_DataExchangeView_OnInitializedAsync.md&amp;value=---%0Auid%3A%20AXOpen.Data.DataExchangeView.OnInitializedAsync%0Asummary%3A%20&#39;*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax&#39;%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span>
<span class="small pull-right mobile-hide">
<a href="https://github.com/ix-ax/AXOpen/blob/dev/src/data/src/AXOpen.Data.Blazor/AxoDataExchange/DataExchangeView.razor.cs/#L95">View Source</a>
<a href="https://github.com/ix-ax/AXOpen/blob/dev/src/data/src/AXOpen.Data.Blazor/AxoDataExchange/DataExchangeView.razor.cs/#L94">View Source</a>
</span>
<a id="AXOpen_Data_DataExchangeView_OnInitializedAsync_" data-uid="AXOpen.Data.DataExchangeView.OnInitializedAsync*"></a>
<h4 id="AXOpen_Data_DataExchangeView_OnInitializedAsync" data-uid="AXOpen.Data.DataExchangeView.OnInitializedAsync">OnInitializedAsync()</h4>
Expand Down
Loading

0 comments on commit c475844

Please sign in to comment.