Configurar a localização de objeto portátil no ASP.NET Core

Por Hisham Bin Ateya e Sébastien Ros.

Este artigo explica as etapas para usar arquivos PO (Objeto Portátil) em um aplicativo ASP.NET Core com a estrutura Orchard Core.

Observação: o Orchard Core não é um produto da Microsoft. A Microsoft não fornece suporte para esse recurso.

Exibir ou baixar código de exemplo (como baixar)

O que é um arquivo PO?

Os arquivos PO são distribuídos como arquivos de texto que contém cadeias de caracteres traduzidas em determinado idioma. Algumas vantagens do uso de arquivos PO em vez de arquivos .resx incluem:

  • Os arquivos PO dão suporte à pluralização, ao contrário dos arquivos .resx.
  • Os arquivos PO não são compilados como os arquivos .resx. Dessa forma, não são necessárias ferramentas especializadas nem etapas de build.
  • Os arquivos PO funcionam bem com ferramentas de colaboração de edição online.

Exemplo

Este é um arquivo PO de exemplo que contém a tradução de duas cadeias de caracteres em francês, incluindo uma com a forma plural:

fr.po

#: Pages/Index.cshtml:13
msgid "Hello world!"
msgstr "Bonjour le monde!"

msgid "There is one item."
msgid_plural "There are {0} items."
msgstr[0] "Il y a un élément."
msgstr[1] "Il y a {0} éléments."

Este exemplo usa a seguinte sintaxe:

  • #:: um comentário que indica o contexto da cadeia de caracteres a ser traduzida. A mesma cadeia de caracteres pode ser traduzida de modo diferente, dependendo do local em que ela está sendo usada.
  • msgid: a cadeia de caracteres não traduzida.
  • msgstr: a cadeia de caracteres traduzida.

No caso de suporte à pluralização, entradas adicionais podem ser definidas.

  • msgid_plural: a cadeia de caracteres no plural não traduzida.
  • msgstr[0]: a cadeia de caracteres traduzida para o caso 0.
  • msgstr[N]: a cadeia de caracteres traduzida para o caso N.

A especificação de arquivo PO pode ser encontrada aqui.

Configurando o suporte a arquivos PO no ASP.NET Core

Este exemplo tem base em um aplicativo Web ASP.NET Core gerado com base em um modelo de projeto do Visual Studio 2022.

Referenciando o pacote

Adicione uma referência ao pacote NuGet OrchardCore.Localization.Core.

Agora, o arquivo .csproj contém uma linha semelhante à seguinte (o número de versão pode variar):

<PackageReference Include="OrchardCore.Localization.Core" Version="1.5.0" />

Registrando o serviço

Adicione os serviços necessários a Program.cs:

builder.Services.AddPortableObjectLocalization();

builder.Services
    .Configure<RequestLocalizationOptions>(options => options
        .AddSupportedCultures("fr", "cs")
        .AddSupportedUICultures("fr", "cs"));

builder.Services
    .AddRazorPages()
    .AddViewLocalization();

Adicione o código a seguir à página do Razor de sua escolha. Index.cshtml é usado neste exemplo.

@page
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
    ViewData["Title"] = "Home";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<p>@Localizer["Hello world!"]</p>

Uma instância IViewLocalizer é injetada e usada para traduzir o texto “Olá, Mundo!”.

Criando um arquivo PO

Crie um arquivo chamado <culture code>.po na pasta raiz do aplicativo. Neste exemplo, o nome do arquivo é fr.po porque o idioma francês é usado:

msgid "Hello world!"
msgstr "Bonjour le monde!"

Esse arquivo armazena a cadeia de caracteres a ser traduzida e a cadeia de caracteres traduzida do francês. As traduções são revertidas para a cultura pai, se necessário. Neste exemplo, o arquivo fr.po é usado se a cultura solicitada é fr-FR ou fr-CA.

Testando o aplicativo

Execute seu aplicativo, o texto Olá, mundo! é exibido.

Navegue para a URL /Index?culture=fr-FR. O texto Bonjour le monde! é exibido.

Pluralização

Os arquivos PO dão suporte a formas de pluralização, que são úteis quando a mesma cadeia de caracteres precisa ser traduzida de modo diferente de acordo com uma cardinalidade. Essa tarefa torna-se complicada pelo fato de que cada idioma define regras personalizadas para selecionar qual cadeia de caracteres será usada de acordo com a cardinalidade.

O pacote de Localização do Orchard fornece uma API para invocar essas diferentes formas plurais automaticamente.

Criando arquivos PO de pluralização

Adicione o seguinte conteúdo ao arquivo fr.po mencionado anteriormente:

msgid "There is one item."
msgid_plural "There are {0} items."
msgstr[0] "Il y a un élément."
msgstr[1] "Il y a {0} éléments."

Consulte O que é um arquivo PO? para obter uma explicação do que representa cada entrada neste exemplo.

Adicionando um idioma usando diferentes formas de pluralização

Cadeias de caracteres em inglês e francês foram usadas no exemplo anterior. O inglês e o francês têm apenas duas formas de pluralização e compartilham as mesmas regras de forma, o que significa que uma cardinalidade de um é mapeada para a primeira forma plural. Qualquer outra cardinalidade é mapeada para a segunda forma plural.

Nem todos os idiomas compartilham as mesmas regras. Isso é ilustrado com o idioma tcheco, que tem três formas plurais.

Crie o arquivo cs.po da seguinte maneira e observe como a pluralização precisa de três traduções diferentes:

msgid "Hello world!"
msgstr "Ahoj světe!!"

msgid "There is one item."
msgid_plural "There are {0} items."
msgstr[0] "Existuje jedna položka."
msgstr[1] "Existují {0} položky."
msgstr[2] "Existuje {0} položek."

Para aceitar localizações para o tcheco, adicione "cs" à lista de culturas com suporte no método Configure:

builder.Services
    .Configure<RequestLocalizationOptions>(options => options
        .AddSupportedCultures("fr", "cs")
        .AddSupportedUICultures("fr", "cs"));

Edite o arquivo Pages/Index.cshtml para renderizar cadeias de caracteres localizadas no plural para várias cardinalidades:

<p>@Localizer.Plural(1, "There is one item.", "There are {0} items.")</p>
<p>@Localizer.Plural(2, "There is one item.", "There are {0} items.")</p>
<p>@Localizer.Plural(5, "There is one item.", "There are {0} items.")</p>

Observação: em um cenário do mundo real, uma variável é usada para representar a contagem. Aqui, repetimos o mesmo código com três valores diferentes para expor um caso específico.

Ao mudar as culturas, o seguinte é observado:

Para /Index:

There is one item.
There are 2 items.
There are 5 items.

Para /Index?culture=fr:

Il y a un élément.
Il y a 2 éléments.
Il y a 5 éléments.

Para /Index?culture=cs:

Existuje jedna položka.
Existují 2 položky.
Existuje 5 položek.

Para a cultura do tcheco, as três traduções são diferentes. As culturas do francês e do inglês compartilham a mesma construção para as duas últimas cadeias de caracteres traduzidas.

Tarefas avançadas

Contextualizando cadeias de caracteres

Os aplicativos costumam conter as cadeias de caracteres a serem traduzidas em vários locais. A mesma cadeia de caracteres pode ter uma tradução diferente em determinados locais em um aplicativo (arquivos de classe ou de exibições do Razor). Um arquivo PO dá suporte à noção de um contexto de arquivo, que pode ser usado para categorizar a cadeia de caracteres que está sendo representada. Usando um contexto de arquivo, uma cadeia de caracteres pode ser traduzida de forma diferente, dependendo do contexto de arquivo (ou de sua ausência).

Os serviços de localização de PO usam o nome da classe completa ou da exibição que é usado ao traduzir uma cadeia de caracteres. Isso é feito definindo o valor na entrada msgctxt.

Considere uma adição mínima ao exemplo anterior de fr.po. Uma página do Razor localizada em Pages/Index.cshtml pode ser definida com o contexto de arquivo definindo o valor da entrada msgctxt reservada:

msgctxt "Views.Home.About"
msgid "Hello world!"
msgstr "Bonjour le monde!"

Com o msgctxt definido assim, a tradução de texto ocorre durante a navegação para /Index?culture=fr-FR. A tradução não ocorre durante a navegação para /Privacy?culture=fr-FR.

Quando não é encontrada a correspondência de nenhuma entrada específica com um contexto de arquivo fornecido, o mecanismo de fallback do Orchard Core procura um arquivo PO apropriado sem contexto. Supondo que não haja nenhum contexto de arquivo específico definido para Pages/Privacy.cshtml, navegar até /Privacy?culture=fr-FR carrega um arquivo PO, como:

msgid "Hello world!"
msgstr "Bonjour le monde!"

Alterando o local dos arquivos PO

A localização padrão dos arquivos PO pode ser alterada em Programs.cs:

services.AddPortableObjectLocalization(options => options.ResourcesPath = "Localization");

Neste exemplo, os arquivos PO são carregados da pasta Localization.

Implementando uma lógica personalizada para encontrar arquivos de localização

Quando uma lógica mais complexa é necessária para localizar arquivos PO, a interface OrchardCore.Localization.PortableObject.ILocalizationFileLocationProvider pode ser implementada e registrada como um serviço. Isso é útil quando arquivos PO podem ser armazenados em locais variáveis ou quando os arquivos precisam ser encontrados em uma hierarquia de pastas.

Usando um idioma pluralizado padrão diferente

O pacote inclui um método de extensão Plural específico a duas formas plurais. Para idiomas que exigem mais formas plurais, crie um método de extensão. Com um método de extensão, você não precisará fornecer nenhum arquivo de localização para o idioma padrão – as cadeias de caracteres originais já estão disponíveis diretamente no código.

Use a sobrecarga Plural(int count, string[] pluralForms, params object[] arguments) mais genérica que aceita uma matriz de cadeia de caracteres de traduções.

Por Sébastien Ros, Scott Addie e Hisham Bin Ateya

Este artigo explica as etapas para usar arquivos PO (Objeto Portátil) em um aplicativo ASP.NET Core com a estrutura Orchard Core.

Observação: o Orchard Core não é um produto da Microsoft. Consequentemente, a Microsoft não fornece suporte para esse recurso.

Exibir ou baixar código de exemplo (como baixar)

O que é um arquivo PO?

Os arquivos PO são distribuídos como arquivos de texto que contém cadeias de caracteres traduzidas em determinado idioma. Algumas vantagens do uso de arquivos PO em vez de arquivos .resx incluem:

  • Os arquivos PO dão suporte à pluralização, ao contrário dos arquivos .resx.
  • Os arquivos PO não são compilados como os arquivos .resx. Dessa forma, não são necessárias ferramentas especializadas nem etapas de build.
  • Os arquivos PO funcionam bem com ferramentas de colaboração de edição online.

Exemplo

Este é um arquivo PO de exemplo que contém a tradução de duas cadeias de caracteres em francês, incluindo uma com sua forma plural:

fr.po

#: Pages/Index.cshtml:13
msgid "Hello world!"
msgstr "Bonjour le monde!"

msgid "There is one item."
msgid_plural "There are {0} items."
msgstr[0] "Il y a un élément."
msgstr[1] "Il y a {0} éléments."

Este exemplo usa a seguinte sintaxe:

  • #:: um comentário que indica o contexto da cadeia de caracteres a ser traduzida. A mesma cadeia de caracteres pode ser traduzida de modo diferente, dependendo do local em que ela está sendo usada.
  • msgid: a cadeia de caracteres não traduzida.
  • msgstr: a cadeia de caracteres traduzida.

No caso de suporte à pluralização, entradas adicionais podem ser definidas.

  • msgid_plural: a cadeia de caracteres no plural não traduzida.
  • msgstr[0]: a cadeia de caracteres traduzida para o caso 0.
  • msgstr[N]: a cadeia de caracteres traduzida para o caso N.

A especificação de arquivo PO pode ser encontrada aqui.

Configurando o suporte a arquivos PO no ASP.NET Core

Este exemplo se baseia em um aplicativo ASP.NET Core MVC gerado com base em um modelo de projeto do Visual Studio 2019.

Referenciando o pacote

Adicione uma referência ao pacote NuGet OrchardCore.Localization.Core.

Agora, o arquivo .csproj contém uma linha semelhante à seguinte (o número de versão pode variar):

<PackageReference Include="OrchardCore.Localization.Core" Version="1.2.0" />

Registrando o serviço

Adicione os serviços necessários ao método ConfigureServices de Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages()
        .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix);

    services.AddPortableObjectLocalization();

    services.Configure<RequestLocalizationOptions>(options => options
        .AddSupportedCultures("fr", "cs")
        .AddSupportedUICultures("fr", "cs")
    );
}

Adicione o middleware necessário ao método Configure de Startup.cs:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseRouting();
    app.UseStaticFiles();

    app.UseRequestLocalization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

Adicione o código a seguir à página do Razor de sua escolha. Index.cshtml é usado neste exemplo.

@page
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
    ViewData["Title"] = "Home";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<p>@Localizer["Hello world!"]</p>

Uma instância IViewLocalizer é injetada e usada para traduzir o texto “Olá, Mundo!”.

Criando um arquivo PO

Crie um arquivo chamado <culture code>.po na pasta raiz do aplicativo. Neste exemplo, o nome do arquivo é fr.po porque o idioma francês é usado:

msgid "Hello world!"
msgstr "Bonjour le monde!"

Esse arquivo armazena a cadeia de caracteres a ser traduzida e a cadeia de caracteres traduzida do francês. As traduções são revertidas para a cultura pai, se necessário. Neste exemplo, o arquivo fr.po é usado se a cultura solicitada é fr-FR ou fr-CA.

Testando o aplicativo

Execute o aplicativo e navegue para a URL /Index. O texto Olá, mundo! é exibido.

Navegue para a URL /Index?culture=fr-FR. O texto Bonjour le monde! é exibido.

Pluralização

Os arquivos PO dão suporte a formas de pluralização, que são úteis quando a mesma cadeia de caracteres precisa ser traduzida de modo diferente de acordo com uma cardinalidade. Essa tarefa torna-se complicada pelo fato de que cada idioma define regras personalizadas para selecionar qual cadeia de caracteres será usada de acordo com a cardinalidade.

O pacote de Localização do Orchard fornece uma API para invocar essas diferentes formas plurais automaticamente.

Criando arquivos PO de pluralização

Adicione o seguinte conteúdo ao arquivo fr.po mencionado anteriormente:

msgid "There is one item."
msgid_plural "There are {0} items."
msgstr[0] "Il y a un élément."
msgstr[1] "Il y a {0} éléments."

Consulte O que é um arquivo PO? para obter uma explicação do que representa cada entrada neste exemplo.

Adicionando um idioma usando diferentes formas de pluralização

Cadeias de caracteres em inglês e francês foram usadas no exemplo anterior. O inglês e o francês têm apenas duas formas de pluralização e compartilham as mesmas regras de forma, o que significa que uma cardinalidade de um é mapeada para a primeira forma plural. Qualquer outra cardinalidade é mapeada para a segunda forma plural.

Nem todos os idiomas compartilham as mesmas regras. Isso é ilustrado com o idioma tcheco, que tem três formas plurais.

Crie o arquivo cs.po da seguinte maneira e observe como a pluralização precisa de três traduções diferentes:

msgid "Hello world!"
msgstr "Ahoj světe!!"

msgid "There is one item."
msgid_plural "There are {0} items."
msgstr[0] "Existuje jedna položka."
msgstr[1] "Existují {0} položky."
msgstr[2] "Existuje {0} položek."

Para aceitar localizações para o tcheco, adicione "cs" à lista de culturas com suporte no método ConfigureServices:

services.Configure<RequestLocalizationOptions>(options => options
                .AddSupportedCultures("fr", "cs")
                .AddSupportedUICultures("fr", "cs")
            );

Edite o arquivo Pages/Index.cshtml para renderizar cadeias de caracteres localizadas no plural para várias cardinalidades:

<p>@Localizer.Plural(1, "There is one item.", "There are {0} items.")</p>
<p>@Localizer.Plural(2, "There is one item.", "There are {0} items.")</p>
<p>@Localizer.Plural(5, "There is one item.", "There are {0} items.")</p>

Observação: em um cenário do mundo real, uma variável é usada para representar a contagem. Aqui, repetimos o mesmo código com três valores diferentes para expor um caso muito específico.

Ao mudar as culturas, o seguinte é observado:

Para /Index:

There is one item.
There are 2 items.
There are 5 items.

Para /Index?culture=fr:

Il y a un élément.
Il y a 2 éléments.
Il y a 5 éléments.

Para /Index?culture=cs:

Existuje jedna položka.
Existují 2 položky.
Existuje 5 položek.

Observe que, para a cultura do tcheco, as três traduções são diferentes. As culturas do francês e do inglês compartilham a mesma construção para as duas últimas cadeias de caracteres traduzidas.

Tarefas avançadas

Contextualizando cadeias de caracteres

Os aplicativos costumam conter as cadeias de caracteres a serem traduzidas em vários locais. A mesma cadeia de caracteres pode ter uma tradução diferente em determinados locais em um aplicativo (arquivos de classe ou de exibições do Razor). Um arquivo PO dá suporte à noção de um contexto de arquivo, que pode ser usado para categorizar a cadeia de caracteres que está sendo representada. Usando um contexto de arquivo, uma cadeia de caracteres pode ser traduzida de forma diferente, dependendo do contexto de arquivo (ou de sua ausência).

Os serviços de localização de PO usam o nome da classe completa ou da exibição que é usado ao traduzir uma cadeia de caracteres. Isso é feito definindo o valor na entrada msgctxt.

Considere uma adição mínima ao exemplo anterior de fr.po. Uma exibição do Razor localizada em Pages/Index.cshtml pode ser definida com o contexto de arquivo definindo o valor da entrada msgctxt reservada:

msgctxt "Pages.Index"
msgid "Hello world!"
msgstr "Bonjour le monde!"

Com o msgctxt definido assim, a tradução de texto ocorre durante a navegação para /Index?culture=fr-FR. A tradução não ocorre durante a navegação para /Privacy?culture=fr-FR.

Quando não é encontrada a correspondência de nenhuma entrada específica com um contexto de arquivo fornecido, o mecanismo de fallback do Orchard Core procura um arquivo PO apropriado sem contexto. Supondo que não haja nenhum contexto de arquivo específico definido para Pages/Privacy.cshtml, navegar até /Privacy?culture=fr-FR carrega um arquivo PO, como:

msgid "Hello world!"
msgstr "Bonjour le monde!"

Alterando o local dos arquivos PO

A localização padrão dos arquivos PO pode ser alterada em ConfigureServices:

services.AddPortableObjectLocalization(options => options.ResourcesPath = "Localization");

Neste exemplo, os arquivos PO são carregados da pasta Localization.

Implementando uma lógica personalizada para encontrar arquivos de localização

Quando uma lógica mais complexa é necessária para localizar arquivos PO, a interface OrchardCore.Localization.PortableObject.ILocalizationFileLocationProvider pode ser implementada e registrada como um serviço. Isso é útil quando arquivos PO podem ser armazenados em locais variáveis ou quando os arquivos precisam ser encontrados em uma hierarquia de pastas.

Usando um idioma pluralizado padrão diferente

O pacote inclui um método de extensão Plural específico a duas formas plurais. Para idiomas que exigem mais formas plurais, crie um método de extensão. Com um método de extensão, você não precisará fornecer nenhum arquivo de localização para o idioma padrão – as cadeias de caracteres originais já estão disponíveis diretamente no código.

Use a sobrecarga Plural(int count, string[] pluralForms, params object[] arguments) mais genérica que aceita uma matriz de cadeia de caracteres de traduções.

Por Sébastien Ros, Scott Addie e Hisham Bin Ateya

Este artigo explica as etapas para usar arquivos PO (Objeto Portátil) em um aplicativo ASP.NET Core com a estrutura Orchard Core.

Observação: o Orchard Core não é um produto da Microsoft. Consequentemente, a Microsoft não fornece suporte para esse recurso.

Exibir ou baixar código de exemplo (como baixar)

O que é um arquivo PO?

Os arquivos PO são distribuídos como arquivos de texto que contém cadeias de caracteres traduzidas em determinado idioma. Algumas vantagens do uso de arquivos PO em vez de arquivos .resx incluem:

  • Os arquivos PO dão suporte à pluralização, ao contrário dos arquivos .resx.
  • Os arquivos PO não são compilados como os arquivos .resx. Dessa forma, não são necessárias ferramentas especializadas nem etapas de build.
  • Os arquivos PO funcionam bem com ferramentas de colaboração de edição online.

Exemplo

Este é um arquivo PO de exemplo que contém a tradução de duas cadeias de caracteres em francês, incluindo uma com sua forma plural:

fr.po

#: Services/EmailService.cs:29
msgid "Enter a comma separated list of email addresses."
msgstr "Entrez une liste d'emails séparés par une virgule."

#: Views/Email.cshtml:112
msgid "The email address is \"{0}\"."
msgid_plural "The email addresses are \"{0}\"."
msgstr[0] "L'adresse email est \"{0}\"."
msgstr[1] "Les adresses email sont \"{0}\""

Este exemplo usa a seguinte sintaxe:

  • #:: um comentário que indica o contexto da cadeia de caracteres a ser traduzida. A mesma cadeia de caracteres pode ser traduzida de modo diferente, dependendo do local em que ela está sendo usada.
  • msgid: a cadeia de caracteres não traduzida.
  • msgstr: a cadeia de caracteres traduzida.

No caso de suporte à pluralização, entradas adicionais podem ser definidas.

  • msgid_plural: a cadeia de caracteres no plural não traduzida.
  • msgstr[0]: a cadeia de caracteres traduzida para o caso 0.
  • msgstr[N]: a cadeia de caracteres traduzida para o caso N.

A especificação de arquivo PO pode ser encontrada aqui.

Configurando o suporte a arquivos PO no ASP.NET Core

Este exemplo se baseia em um aplicativo ASP.NET Core MVC gerado com base em um modelo de projeto do Visual Studio 2017.

Referenciando o pacote

Adicione uma referência ao pacote NuGet OrchardCore.Localization.Core.

Agora, o arquivo .csproj contém uma linha semelhante à seguinte (o número de versão pode variar):

<PackageReference Include="OrchardCore.Localization.Core" Version="1.0.0" />

Registrando o serviço

Adicione os serviços necessários ao método ConfigureServices de Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix);

    services.AddPortableObjectLocalization();

    services.Configure<RequestLocalizationOptions>(options =>
        {
            var supportedCultures = new List<CultureInfo>
            {
                new CultureInfo("en-US"),
                new CultureInfo("en"),
                new CultureInfo("fr-FR"),
                new CultureInfo("fr")
            };

            options.DefaultRequestCulture = new RequestCulture("en-US");
            options.SupportedCultures = supportedCultures;
            options.SupportedUICultures = supportedCultures;
        });
}

Adicione o middleware necessário ao método Configure de Startup.cs:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseRouting();
    app.UseStaticFiles();

    app.UseRequestLocalization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

Adicione o código a seguir à exibição do Razor de sua escolha. About.cshtml é usado neste exemplo.

@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer

<p>@Localizer["Hello world!"]</p>

Uma instância IViewLocalizer é injetada e usada para traduzir o texto “Olá, Mundo!”.

Criando um arquivo PO

Crie um arquivo chamado <culture code>.po na pasta raiz do aplicativo. Neste exemplo, o nome do arquivo é fr.po porque o idioma francês é usado:

msgid "Hello world!"
msgstr "Bonjour le monde!"

Esse arquivo armazena a cadeia de caracteres a ser traduzida e a cadeia de caracteres traduzida do francês. As traduções são revertidas para a cultura pai, se necessário. Neste exemplo, o arquivo fr.po é usado se a cultura solicitada é fr-FR ou fr-CA.

Testando o aplicativo

Execute o aplicativo e navegue para a URL /Home/About. O texto Olá, mundo! é exibido.

Navegue para a URL /Home/About?culture=fr-FR. O texto Bonjour le monde! é exibido.

Pluralização

Os arquivos PO dão suporte a formas de pluralização, que são úteis quando a mesma cadeia de caracteres precisa ser traduzida de modo diferente de acordo com uma cardinalidade. Essa tarefa torna-se complicada pelo fato de que cada idioma define regras personalizadas para selecionar qual cadeia de caracteres será usada de acordo com a cardinalidade.

O pacote de Localização do Orchard fornece uma API para invocar essas diferentes formas plurais automaticamente.

Criando arquivos PO de pluralização

Adicione o seguinte conteúdo ao arquivo fr.po mencionado anteriormente:

msgid "There is one item."
msgid_plural "There are {0} items."
msgstr[0] "Il y a un élément."
msgstr[1] "Il y a {0} éléments."

Consulte O que é um arquivo PO? para obter uma explicação do que representa cada entrada neste exemplo.

Adicionando um idioma usando diferentes formas de pluralização

Cadeias de caracteres em inglês e francês foram usadas no exemplo anterior. O inglês e o francês têm apenas duas formas de pluralização e compartilham as mesmas regras de forma, o que significa que uma cardinalidade de um é mapeada para a primeira forma plural. Qualquer outra cardinalidade é mapeada para a segunda forma plural.

Nem todos os idiomas compartilham as mesmas regras. Isso é ilustrado com o idioma tcheco, que tem três formas plurais.

Crie o arquivo cs.po da seguinte maneira e observe como a pluralização precisa de três traduções diferentes:

msgid "Hello world!"
msgstr "Ahoj světe!!"

msgid "There is one item."
msgid_plural "There are {0} items."
msgstr[0] "Existuje jedna položka."
msgstr[1] "Existují {0} položky."
msgstr[2] "Existuje {0} položek."

Para aceitar localizações para o tcheco, adicione "cs" à lista de culturas com suporte no método ConfigureServices:

var supportedCultures = new List<CultureInfo>
{
    new CultureInfo("en-US"),
    new CultureInfo("en"),
    new CultureInfo("fr-FR"),
    new CultureInfo("fr"),
    new CultureInfo("cs")
};

Edite o arquivo Views/Home/About.cshtml para renderizar cadeias de caracteres localizadas no plural para várias cardinalidades:

<p>@Localizer.Plural(1, "There is one item.", "There are {0} items.")</p>
<p>@Localizer.Plural(2, "There is one item.", "There are {0} items.")</p>
<p>@Localizer.Plural(5, "There is one item.", "There are {0} items.")</p>

Observação: em um cenário do mundo real, uma variável é usada para representar a contagem. Aqui, repetimos o mesmo código com três valores diferentes para expor um caso muito específico.

Ao mudar as culturas, o seguinte é observado:

Para /Home/About:

There is one item.
There are 2 items.
There are 5 items.

Para /Home/About?culture=fr:

Il y a un élément.
Il y a 2 éléments.
Il y a 5 éléments.

Para /Home/About?culture=cs:

Existuje jedna položka.
Existují 2 položky.
Existuje 5 položek.

Observe que, para a cultura do tcheco, as três traduções são diferentes. As culturas do francês e do inglês compartilham a mesma construção para as duas últimas cadeias de caracteres traduzidas.

Tarefas avançadas

Contextualizando cadeias de caracteres

Os aplicativos costumam conter as cadeias de caracteres a serem traduzidas em vários locais. A mesma cadeia de caracteres pode ter uma tradução diferente em determinados locais em um aplicativo (arquivos de classe ou de exibições do Razor). Um arquivo PO dá suporte à noção de um contexto de arquivo, que pode ser usado para categorizar a cadeia de caracteres que está sendo representada. Usando um contexto de arquivo, uma cadeia de caracteres pode ser traduzida de forma diferente, dependendo do contexto de arquivo (ou de sua ausência).

Os serviços de localização de PO usam o nome da classe completa ou da exibição que é usado ao traduzir uma cadeia de caracteres. Isso é feito definindo o valor na entrada msgctxt.

Considere uma adição mínima ao exemplo anterior de fr.po. Uma exibição do Razor localizada em Views/Home/About.cshtml pode ser definida com o contexto de arquivo definindo o valor da entrada msgctxt reservada:

msgctxt "Views.Home.About"
msgid "Hello world!"
msgstr "Bonjour le monde!"

Com o msgctxt definido assim, a tradução de texto ocorre durante a navegação para /Home/About?culture=fr-FR. A tradução não ocorre durante a navegação para /Home/Contact?culture=fr-FR.

Quando não é encontrada a correspondência de nenhuma entrada específica com um contexto de arquivo fornecido, o mecanismo de fallback do Orchard Core procura um arquivo PO apropriado sem contexto. Supondo que não haja nenhum contexto de arquivo específico definido para Views/Home/Contact.cshtml, navegar até /Home/Contact?culture=fr-FR carrega um arquivo PO, como:

msgid "Hello world!"
msgstr "Bonjour le monde!"

Alterando o local dos arquivos PO

A localização padrão dos arquivos PO pode ser alterada em ConfigureServices:

services.AddPortableObjectLocalization(options => options.ResourcesPath = "Localization");

Neste exemplo, os arquivos PO são carregados da pasta Localization.

Implementando uma lógica personalizada para encontrar arquivos de localização

Quando uma lógica mais complexa é necessária para localizar arquivos PO, a interface OrchardCore.Localization.PortableObject.ILocalizationFileLocationProvider pode ser implementada e registrada como um serviço. Isso é útil quando arquivos PO podem ser armazenados em locais variáveis ou quando os arquivos precisam ser encontrados em uma hierarquia de pastas.

Usando um idioma pluralizado padrão diferente

O pacote inclui um método de extensão Plural específico a duas formas plurais. Para idiomas que exigem mais formas plurais, crie um método de extensão. Com um método de extensão, você não precisará fornecer nenhum arquivo de localização para o idioma padrão – as cadeias de caracteres originais já estão disponíveis diretamente no código.

Use a sobrecarga Plural(int count, string[] pluralForms, params object[] arguments) mais genérica que aceita uma matriz de cadeia de caracteres de traduções.