Add localization

This commit is contained in:
2020-05-21 18:52:40 +01:00
parent 4e1a99ea8c
commit c5783a452c
13 changed files with 392 additions and 29 deletions

View File

@@ -1,27 +1,30 @@
@using Microsoft.AspNetCore.Identity @using Marechai.Shared
@using Microsoft.AspNetCore.Identity
@using Microsoft.Extensions.Localization
@inject SignInManager<IdentityUser> SignInManager @inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager @inject UserManager<IdentityUser> UserManager
@inject StringLocalizer<NavMenu> L
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<ul class="navbar-nav"> <ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User)) @if (SignInManager.IsSignedIn(User))
{ {
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity.Name!</a> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">@string.Format(L["Hello {0}!"], User.Identity.Name)</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="/" method="post"> <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="/" method="post">
<button type="submit" class="nav-link btn btn-link text-dark">Logout</button> <button type="submit" class="nav-link btn btn-link text-dark">@L["Logout"]</button>
</form> </form>
</li> </li>
} }
else else
{ {
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">@L["Register"]</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">@L["Login"]</a>
</li> </li>
} }
</ul> </ul>

View File

@@ -2,7 +2,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
<Version>3.0.99.928</Version> <Version>3.0.99.933</Version>
<Company>Canary Islands Computer Museum</Company> <Company>Canary Islands Computer Museum</Company>
<Copyright>Copyright © 2003-2020 Natalia Portillo</Copyright> <Copyright>Copyright © 2003-2020 Natalia Portillo</Copyright>
<Product>Canary Islands Computer Museum Website</Product> <Product>Canary Islands Computer Museum Website</Product>
@@ -112,4 +112,10 @@
<ExcludeFromSingleFile>true</ExcludeFromSingleFile> <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content> </Content>
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\Services\NewsService.es.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>NewsService.es.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project> </Project>

View File

@@ -1,8 +1,8 @@
@page "/" @page "/"
@using Marechai.ViewModels
@inherits OwningComponentBase<NewsService> @inherits OwningComponentBase<NewsService>
@inject IStringLocalizer<NewsService> L
<h2>News</h2> <h2>@L["News"]</h2>
@foreach (var news in _news) @foreach (var news in _news)
{ {
<table border="0" width="100%"> <table border="0" width="100%">

View File

@@ -0,0 +1,16 @@
using System.Globalization;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Marechai.Pages
{
public class HostModel : PageModel
{
public void OnGet() => HttpContext.Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.
MakeCookieValue(new
RequestCulture(CultureInfo.CurrentCulture,
CultureInfo.
CurrentUICulture)));
}
}

View File

@@ -0,0 +1,157 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- ReSharper disable MarkupTextTypo -->
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="News" xml:space="preserve">
<value>Noticias</value>
<comment>News</comment>
</data>
<data name="New computer in database" xml:space="preserve">
<value>Nuevo ordenador en la base de datos</value>
<comment>New computer in database</comment>
</data>
<data name="New console in database" xml:space="preserve">
<value>Nueva videoconsola en la base de datos</value>
<comment>New console in database</comment>
</data>
<data name="New computer in collection" xml:space="preserve">
<value>Nuevo ordenador en la colección</value>
<comment>New computer in collection</comment>
</data>
<data name="New console in collection" xml:space="preserve">
<value>Nueva videoconsola en la base de datos</value>
<comment>New console in collection</comment>
</data>
<data name="Updated computer in database" xml:space="preserve">
<value>Ordenador actualizado en la base de datos</value>
<comment>Updated computer in database</comment>
</data>
<data name="Updated console in database" xml:space="preserve">
<value>Videoconsola actualizada en la base de datos</value>
<comment>Updated console in database</comment>
</data>
<data name="Updated computer in collection" xml:space="preserve">
<value>Ordenador actualizado en la colección</value>
<comment>Updated computer in collection</comment>
</data>
<data name="Updated console in collection" xml:space="preserve">
<value>Videoconsola actualizada en la colección</value>
<comment>Updated console in collection</comment>
</data>
</root>

View File

@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- ReSharper disable MarkupTextTypo -->
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="News" xml:space="preserve">
<value>Noticias</value>
<comment>News</comment>
</data>
<data name="Hello {0}!" xml:space="preserve">
<value>¡Hola {0}!</value>
<comment>Salutes logged-in user</comment>
</data>
<data name="Logout" xml:space="preserve">
<value>Cerrar sesión</value>
<comment>Logout</comment>
</data>
<data name="Register" xml:space="preserve">
<value>Registrarse</value>
<comment>Register</comment>
</data>
<data name="Login" xml:space="preserve">
<value>Iniciar sesión</value>
<comment>Login</comment>
</data>
<data name="About" xml:space="preserve">
<value>Acerca de</value>
<comment>About</comment>
</data>
</root>

View File

@@ -33,14 +33,20 @@ using System.Linq;
using Marechai.Database; using Marechai.Database;
using Marechai.Database.Models; using Marechai.Database.Models;
using Marechai.ViewModels; using Marechai.ViewModels;
using Microsoft.Extensions.Localization;
namespace Marechai.Services namespace Marechai.Services
{ {
public class NewsService public class NewsService
{ {
readonly MarechaiContext _context; readonly MarechaiContext _context;
readonly IStringLocalizer<NewsService> _l;
public NewsService(MarechaiContext context) => _context = context; public NewsService(MarechaiContext context, IStringLocalizer<NewsService> localizer)
{
_context = context;
_l = localizer;
}
public List<NewsViewModel> GetNews() public List<NewsViewModel> GetNews()
{ {
@@ -56,49 +62,49 @@ namespace Marechai.Services
switch(@new.Type) switch(@new.Type)
{ {
case NewsType.NewComputerInDb: case NewsType.NewComputerInDb:
news.Add(new NewsViewModel(@new.AddedId, "New computer in database", @new.Date, "Machine", news.Add(new NewsViewModel(@new.AddedId, _l["New computer in database"], @new.Date, "Machine",
$"{machine.Company.Name} {machine.Name}")); $"{machine.Company.Name} {machine.Name}"));
break; break;
case NewsType.NewConsoleInDb: case NewsType.NewConsoleInDb:
news.Add(new NewsViewModel(@new.AddedId, "New console in database", @new.Date, "Machine", news.Add(new NewsViewModel(@new.AddedId, _l["New console in database"], @new.Date, "Machine",
$"{machine.Company.Name} {machine.Name}")); $"{machine.Company.Name} {machine.Name}"));
break; break;
case NewsType.NewComputerInCollection: case NewsType.NewComputerInCollection:
news.Add(new NewsViewModel(@new.AddedId, "New computer in collection", @new.Date, "Machine", news.Add(new NewsViewModel(@new.AddedId, _l["New computer in collection"], @new.Date, "Machine",
$"{machine.Company.Name} {machine.Name}")); $"{machine.Company.Name} {machine.Name}"));
break; break;
case NewsType.NewConsoleInCollection: case NewsType.NewConsoleInCollection:
news.Add(new NewsViewModel(@new.AddedId, "New console in collection", @new.Date, "Machine", news.Add(new NewsViewModel(@new.AddedId, _l["New console in collection"], @new.Date, "Machine",
$"{machine.Company.Name} {machine.Name}")); $"{machine.Company.Name} {machine.Name}"));
break; break;
case NewsType.UpdatedComputerInDb: case NewsType.UpdatedComputerInDb:
news.Add(new NewsViewModel(@new.AddedId, "Updated computer in database", @new.Date, "Machine", news.Add(new NewsViewModel(@new.AddedId, _l["Updated computer in database"], @new.Date,
$"{machine.Company.Name} {machine.Name}")); "Machine", $"{machine.Company.Name} {machine.Name}"));
break; break;
case NewsType.UpdatedConsoleInDb: case NewsType.UpdatedConsoleInDb:
news.Add(new NewsViewModel(@new.AddedId, "Updated console in database", @new.Date, "Machine", news.Add(new NewsViewModel(@new.AddedId, _l["Updated console in database"], @new.Date,
$"{machine.Company.Name} {machine.Name}")); "Machine", $"{machine.Company.Name} {machine.Name}"));
break; break;
case NewsType.UpdatedComputerInCollection: case NewsType.UpdatedComputerInCollection:
news.Add(new NewsViewModel(@new.AddedId, "Updated computer in collection", @new.Date, "Machine", news.Add(new NewsViewModel(@new.AddedId, _l["Updated computer in collection"], @new.Date,
$"{machine.Company.Name} {machine.Name}")); "Machine", $"{machine.Company.Name} {machine.Name}"));
break; break;
case NewsType.UpdatedConsoleInCollection: case NewsType.UpdatedConsoleInCollection:
news.Add(new NewsViewModel(@new.AddedId, "Updated console in collection", @new.Date, "Machine", news.Add(new NewsViewModel(@new.AddedId, _l["Updated console in collection"], @new.Date,
$"{machine.Company.Name} {machine.Name}")); "Machine", $"{machine.Company.Name} {machine.Name}"));
break; break;

View File

@@ -28,15 +28,20 @@
// Copyright © 2003-2020 Natalia Portillo // Copyright © 2003-2020 Natalia Portillo
*******************************************************************************/ *******************************************************************************/
using Marechai.Shared;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
namespace Marechai.Services namespace Marechai.Services
{ {
public static class Register public static class Register
{ {
internal static void RegisterServices(IServiceCollection services) => internal static void RegisterServices(IServiceCollection services)
{
services.AddSingleton<StringLocalizer<NavMenu>>();
// TODO: User reflection // TODO: Use reflection
services.AddScoped<NewsService>(); services.AddScoped<NewsService>();
}
} }
} }

View File

@@ -1,4 +1,5 @@
@inherits LayoutComponentBase @inherits LayoutComponentBase
@inject StringLocalizer<NavMenu> L
<div class="sidebar"> <div class="sidebar">
<NavMenu /> <NavMenu />
@@ -7,7 +8,7 @@
<div class="main"> <div class="main">
<div class="top-row px-4 auth"> <div class="top-row px-4 auth">
<LoginDisplay/> <LoginDisplay/>
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a> <a href="https://docs.microsoft.com/aspnet/" target="_blank">@L["About"]</a>
</div> </div>
<div class="content px-4"> <div class="content px-4">

View File

@@ -1,4 +1,6 @@
<div class="top-row pl-4 navbar navbar-dark"> @inject StringLocalizer<NavMenu> L
<div class="top-row pl-4 navbar navbar-dark">
<a class="navbar-brand" href="">Marechai</a> <a class="navbar-brand" href="">Marechai</a>
<button class="navbar-toggler" @onclick="ToggleNavMenu"> <button class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
@@ -9,7 +11,7 @@
<ul class="nav flex-column"> <ul class="nav flex-column">
<li class="nav-item px-3"> <li class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All"> <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="fa fa-newspaper" aria-hidden="true"></span>&nbsp;News <span class="fa fa-newspaper" aria-hidden="true"></span>&nbsp;@L["News"]
</NavLink> </NavLink>
</li> </li>
</ul> </ul>

View File

@@ -28,6 +28,7 @@
// Copyright © 2003-2020 Natalia Portillo // Copyright © 2003-2020 Natalia Portillo
*******************************************************************************/ *******************************************************************************/
using System.Globalization;
using Marechai.Areas.Identity; using Marechai.Areas.Identity;
using Marechai.Database.Models; using Marechai.Database.Models;
using Marechai.Services; using Marechai.Services;
@@ -35,6 +36,7 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Localization;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@@ -45,6 +47,11 @@ namespace Marechai
// DO NOT MAKE STATIC // DO NOT MAKE STATIC
public class Startup public class Startup
{ {
readonly CultureInfo[] supportedCultures =
{
new CultureInfo("en-US"), new CultureInfo("es")
};
public Startup(IConfiguration configuration) => Configuration = configuration; public Startup(IConfiguration configuration) => Configuration = configuration;
IConfiguration Configuration { get; } IConfiguration Configuration { get; }
@@ -66,6 +73,8 @@ namespace Marechai
services. services.
AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>(); AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
services.AddLocalization(options => options.ResourcesPath = "Resources");
Register.RegisterServices(services); Register.RegisterServices(services);
} }
@@ -85,6 +94,17 @@ namespace Marechai
app.UseHsts(); app.UseHsts();
} }
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US"),
// Formatting numbers, dates, etc.
SupportedCultures = supportedCultures,
// UI strings that we have localized.
SupportedUICultures = supportedCultures
});
app.UseHttpsRedirection(); app.UseHttpsRedirection();
app.UseStaticFiles(); app.UseStaticFiles();

View File

@@ -8,3 +8,5 @@
@using Marechai @using Marechai
@using Marechai.Shared @using Marechai.Shared
@using Marechai.Services @using Marechai.Services
@using Marechai.ViewModels
@using Microsoft.Extensions.Localization

View File

@@ -1 +1 @@
{"projectId":"84f7bc66-384b-4564-befb-04612b16d278","projectName":"Marechai"} {"projectId":"fd3f3857-80b9-4ed7-90f8-c6ebd0ae449f","projectName":"Marechai"}