Fermer

avril 26, 2024

Principes de base de Blazor : localisation à l’aide de fichiers de ressources

Principes de base de Blazor : localisation à l’aide de fichiers de ressources


Dans cet article, nous apprendrons comment localiser les applications Blazor à l’aide de fichiers de ressources.

La solution présentée dans cet article fonctionne pour Blazor Server et le nouveau modèle de projet Blazor Web App de .NET 8. Cependant, elle ne fonctionne pas pour les projets WebAssembly.

Tu peux accéder au code utilisé dans cet exemple sur GitHub.

Introduction

Nous allons implémenter la localisation pour une application Web Blazor. Cela nous permettra de traduire l’application Web en plusieurs langues.

Une application Blazor avec un sélecteur de culture en haut à droite où vous pouvez sélectionner l'une des langues prises en charge.  Le contenu de la page et du menu est rendu dans la langue sélectionnée - l'allemand.

Une application Blazor avec un sélecteur de culture en haut à droite où vous pouvez sélectionner l'une des langues prises en charge.  Le contenu de la page et du menu est rendu dans la langue sélectionnée - anglais.

Le projet terminé ressemblera à ceci. Il contient un sélecteur de langue en haut à droite et affiche les options du menu à gauche ainsi que le contenu de la page d’accueil dans la langue sélectionnée.

Installation des packages NuGet requis

Puisque nous utilisons .NET, nous n’avons pas besoin de réinventer la roue. Notre solution s’appuie sur Microsoft.Extensions.Localisation emballer.

Dans un projet Blazor nouvellement créé basé sur le modèle de projet Blazor Web App de projet unique de .NET 8, nous installons le package.

L'explorateur de packages Nuget avec le package Microsoft.Extensions.Localizations installé et sélectionné.

Ensuite, nous ouvrons le fichier Program.cs et ajoutons les services requis au conteneur de services.

builder.Services.AddLocalization();

Nous devons également configurer le middleware de localisation sur l’hôte de l’application. Je suggère de l’installer juste après le builder.Build() appelez pour vous assurer que le middleware de localisation s’exécute le plus tôt possible.

string[] supportedCultures = ["en-US", "de-CH"];
var localizationOptions = new RequestLocalizationOptions()
    .SetDefaultCulture(supportedCultures[0])
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);

Nous devons configurer le UseRequestLocalization méthode avec un RequestLocalizationOptions objet. Nous utilisons des initialiseurs de collection et ajoutons en-US et de-CH comme cultures. Nous utilisons ensuite le tableau pour remplir les options requises.

Création des fichiers de traduction en tant que fichiers de ressources

Nous créons un Locales dossier qui contiendra nos textes traduits. Dans ce dossier, nous créons un nouveau fichier de ressources et le nommons Resources.resx.

Le système de ressources de .NET fonctionne avec un outil personnalisé. Nous devons ouvrir les propriétés du fichier dans l’Explorateur de solutions et définir le PublicResXFileCodeGenerator comme outil personnalisé.

Il est livré avec Visual Studio et doit être installé immédiatement. Lorsque nous enregistrons le fichier, un fichier de concepteur doit être généré en arrière-plan. Chaque fois que nous ajoutons une ressource au dictionnaire et enregistrons le fichier, le fichier du concepteur doit être régénéré.

Indice: Parfois, le fichier du concepteur ne sera pas généré. Vous pouvez soit décharger et recharger le projet dans Visual Studio, soit redémarrer Visual Studio. La plupart du temps, cela résoudra le problème. Sinon, vous souhaiterez peut-être redémarrer votre ordinateur.

Visual Studio avec le fichier de ressources en anglais ouvert.

Ajoutons les ressources dont nous avons besoin pour cette application de démonstration.

Ensuite, nous souhaitons spécifier la culture de ce fichier de ressources dans son nom de fichier. Nous le renommons de Resources.resx à Resources.en-US.resx. J’ai appris que si nous créons le fichier avec ce nom depuis le début, nous avons encore plus de problèmes avec la génération du fichier de conception.

Nous créons également un autre fichier de ressources et le nommons Resources.de-CH.resx où nous stockerons les traductions allemandes.

Visual Studio avec le fichier de ressources allemand ouvert.

Nous sommes maintenant prêts à utiliser les chaînes localisées dans notre application Blazor.

Utilisation des ressources dans les composants Blazor

Dans le Home composant page, nous remplaçons le contenu du fichier par le code suivant :

@page "https://www.telerik.com/"
@using Microsoft.Extensions.Localization
@using BlazorLocalization.Locales;
@using System.Globalization
@inject IStringLocalizer<Resources> localizer

<PageTitle>@localizer["Home"]</PageTitle>

@Thread.CurrentThread.CurrentCulture;
@Thread.CurrentThread.CurrentUICulture;

<h1>@localizer["HomeTitle"]</h1>

@localizer["HomeText"]

Nous avons besoin de quelques instructions using donnant accès au Localization espace de noms ainsi que notre Resources classe contenant les chaînes localisées.

Indice: Nous pouvons également déplacer les instructions using dans le _Imports.razor déposer. Cela nous permettra d’accéder aux classes dans ces espaces de noms sans ajouter explicitement une instruction using dans chaque composant.

Ensuite, nous utilisons la directive inject pour créer une instance du générique IStringLocalizer classe. Nous fournissons notre Resources class comme argument de type générique.

Le localizer expose un indexeur, nous donnant accès aux chaînes traduites. Nous utilisons la syntaxe suivante pour accéder à la valeur dans le HomeTitle jeton:

@localizer["HomeTitle"]

L’accès aux chaînes traduites à l’aide du localisateur de chaînes est simple.

Nous souhaitons également utiliser le localisateur de chaînes dans le NavMenu composant pour traduire les éléments de menu. Nous utilisons le code suivant dans le NavMenu.razor déposer:

@using Microsoft.Extensions.Localization
@using BlazorLocalization.Locales;
@using System.Globalization
@inject IStringLocalizer<Resources> localizer

<div class="top-row ps-3 navbar navbar-dark">
    <div class="container-fluid">
        <a class="navbar-brand" href="">Blazor Localization</a>
    </div>
</div>

<input type="checkbox" title="Navigation menu" class="navbar-toggler" />

<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
    <nav class="flex-column">
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> @localizer["MenuHome"]
            </NavLink>
        </div>

        <div class="nav-item px-3">
            <NavLink class="nav-link" href="counter">
                <span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> @localizer["MenuCounter"]
            </NavLink>
        </div>

        <div class="nav-item px-3">
            <NavLink class="nav-link" href="weather">
                <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> @localizer["MenuWeather"]
            </NavLink>
        </div>
    </nav>
</div>

Encore une fois, nous avons quelques instructions using et nous utilisons l’indexeur du localizer variable de type générique IStringLocalizer avec le Resources classe comme argument de type.

Le composant CultureSelector

Maintenant que nous avons les textes traduits dans nos fichiers de ressources et que nous savons comment accéder aux informations dans les composants Blazor, nous voulons pouvoir changer de culture depuis l’application Blazor.

Nous créons un nouveau composant dans le Layouts dossier et nommez-le CultureSelectoret insérez le code suivant :

@inject NavigationManager Navigation
@using System.Globalization

<div>
    <select @bind="Culture">
        <option value="en-US">English</option>
        <option value="de-CH">German</option>
    </select>
</div>

@code
{
    protected override void OnInitialized()
    {
        Culture = CultureInfo.CurrentCulture;
    }

    private CultureInfo Culture
    {
        get
        {
            return CultureInfo.CurrentCulture;
        }
        set
        {
            if (CultureInfo.CurrentCulture != value)
            {
                var uri = new Uri(Navigation.Uri)
                    .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
                var cultureEscaped = Uri.EscapeDataString(value.Name);
                var uriEscaped = Uri.EscapeDataString(uri);

                var fullUri = $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}";
                Navigation.NavigateTo(fullUri, forceLoad: true);
            }
        }
    }
}

Le modèle de composant utilise un HTML select élément qui affiche une liste déroulante comprenant une liste de toutes les cultures disponibles.

Dans la section code, nous initialisons la culture actuelle en utilisant le CultureInfo classe. Nous mettons également en œuvre un Culture propriété que nous lions à l’élément select dans le code du modèle. Il contient un getter simple et un setter plus avancé.

Dans le setter, nous vérifions si la valeur sélectionnée est différente de la culture actuelle. Si cela est vrai, nous construisons un URI incluant la valeur culturelle et déclenchons une navigation de page interne à l’aide du NavigationManager.

Assurez-vous de fournir des informations fidèles aux forceLoad argument pour garantir que la navigation interne sera exécutée.

Gestion des changements de culture à l’aide d’un contrôleur

Chaque fois que nous sélectionnons une culture différente dans le CultureSelector composant, une navigation de page interne devrait avoir lieu. Cependant, nous n’avons pas encore implémenté la page cible.

Ajoutons un nouveau dossier Controllers dans le dossier racine et créons un contrôleur MVC vide nommé CultureController pour la base de l’implémentation du contrôleur suivante.

using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;

namespace BlazorLocalization.Controllers;

[Route("[controller]/[action]")]
public class CultureController : Controller
{
    public IActionResult Set(string culture, string redirectUri)
    {
        if (culture != null)
        {
            var requestCulture = new RequestCulture(culture, culture);
            var cookieName = CookieRequestCultureProvider.DefaultCookieName;
            var cookieValue = CookieRequestCultureProvider.MakeCookieValue(requestCulture);

            HttpContext.Response.Cookies.Append(cookieName, cookieValue);
        }

        return LocalRedirect(redirectUri);
    }
}

Nous mettons en œuvre un Set méthode qui accepte deux paramètres. Il a une culture et un argument redirectUri, tous deux de type string.

Si la culture fournie n’est pas nulle, nous créons une nouvelle instance du système intégré RequestCulture objet et fournir les instances comme valeur d’un cookie.

Lors de l’utilisation du Localization Package NuGet installé au début, nous pouvons choisir parmi différentes options, comment changer la culture. L’utilisation de cookies est l’une des solutions les plus simples et elle a très bien fonctionné pour moi jusqu’à présent.

À la fin de la méthode, nous devons nous assurer que nous ajoutons le cookie créé à la réponse de notre requête HTTP et exécutons la redirection vers le redirectUri.

Pour que l’application Blazor soit consciente du contrôleur nouvellement implémenté, nous devons enregistrer les services gérant les contrôleurs ASP.NET Core dans le fichier Program.cs déposer.

Nous ajoutons la ligne suivante après le AddLocalization appel:

builder.Services.AddControllers();

Et nous devons également ajouter l’enregistrement du middleware suivant sur l’hôte de l’application Web :

app.MapControllers();

L’ordre n’a pas beaucoup d’importance, mais j’enregistre généralement les contrôleurs avant le MapRazorComponent<App>() inscription.

Conclusion

Le Microsoft.Extensions.Localization Le package NuGet nous fournit des types qui nous permettent d’implémenter la localisation avec quelques lignes de code et des outils .NET bien connus, tels que des fichiers de ressources.

Assurez-vous d’enregistrer les services requis dans le Program.cs fichier, et vous devriez être prêt à y aller assez rapidement.

Si vous souhaitez avoir plus de sécurité de type lors de l’accès aux chaînes localisées, vous pouvez également implémenter un enum contenant les clés des fichiers ressources et utiliser le enum au lieu de chaînes magiques lors de l’utilisation de l’indexeur du IStringLocalizer interface.

Si vous souhaitez en savoir plus sur le développement de Blazor, vous pouvez regarder mon cours intensif Blazor gratuit sur YouTube. Et restez à l’écoute du blog Telerik pour en savoir plus Les bases du Blazor.




Source link