Skip to content

Commit

Permalink
add i18n project
Browse files Browse the repository at this point in the history
  • Loading branch information
yaochangyu committed Dec 19, 2024
1 parent d91ccd9 commit 433a516
Show file tree
Hide file tree
Showing 11 changed files with 872 additions and 0 deletions.
670 changes: 670 additions & 0 deletions i18N/.gitignore

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions i18N/Lab.i18N.WebApi/DemoController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;

namespace Lab.i18N.WebApi;

[ApiController]
public class DemoController(IStringLocalizer<DemoController> localizer) : ControllerBase
{
[HttpGet]
[Route("api/v1/demo", Name = "GetDemo")]
public IActionResult Get()
{
var desc = localizer["about.description"];

return Ok(new
{
desc
});
}
}
31 changes: 31 additions & 0 deletions i18N/Lab.i18N.WebApi/HeaderRequestCultureProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.Primitives;

namespace Lab.i18N.WebApi;

public class HeaderRequestCultureProvider : RequestCultureProvider
{
public override async Task<ProviderCultureResult?> DetermineProviderCultureResult(HttpContext httpContext)
{
// 檢查是否有 Accept-Language Header
if (!httpContext.Request.Headers.TryGetValue("Accept-Language", out var acceptLanguage))
{
return await Task.FromResult<ProviderCultureResult?>(null);
}

// 解析 Header 值,取第一個語言
var languages = acceptLanguage.ToString()
.Split(',', StringSplitOptions.RemoveEmptyEntries)
.Select(lang => lang.Split(';').FirstOrDefault())
.ToList()
;

if (languages.Any())
{
var languageSegments = languages.Select(lang => new StringSegment(lang)).ToList();
return await Task.FromResult(new ProviderCultureResult(languageSegments));
}

return await Task.FromResult<ProviderCultureResult?>(null);
}
}
36 changes: 36 additions & 0 deletions i18N/Lab.i18N.WebApi/Lab.i18N.WebApi.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="I18Next.Net.AspNetCore" Version="1.0.0" />
<PackageReference Include="I18Next.Net.Extensions" Version="1.0.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0"/>
</ItemGroup>

<ItemGroup>
<_ContentIncludedByDefault Remove="wwwroot\css\site.css" />
<_ContentIncludedByDefault Remove="wwwroot\css\site.min.css" />
<_ContentIncludedByDefault Remove="wwwroot\js\site.js" />
<_ContentIncludedByDefault Remove="wwwroot\js\site.min.js" />
</ItemGroup>

<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>

<ItemGroup>
<Content Update="wwwroot\locales\de\translation.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\locales\en\translation.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

</Project>
6 changes: 6 additions & 0 deletions i18N/Lab.i18N.WebApi/Lab.i18N.WebApi.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@Lab.i18N.WebApi_HostAddress = http://localhost:5092

GET {{Lab.i18N.WebApi_HostAddress}}/weatherforecast/
Accept: application/json

###
54 changes: 54 additions & 0 deletions i18N/Lab.i18N.WebApi/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System.Globalization;
using I18Next.Net.AspNetCore;
using I18Next.Net.Backends;
using I18Next.Net.Extensions;
using Lab.i18N.WebApi;
using Microsoft.AspNetCore.Localization;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
;

// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddI18NextLocalization(i18N =>
{
i18N.Configure(options =>
{
options.DefaultNamespace = "translation";
options.DefaultLanguage = "de";
options.FallbackLanguages = new[] { "en" };
});

i18N.IntegrateToAspNetCore()
.AddBackend(new JsonFileBackend("wwwroot/locales"));
});
var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}

app.UseRequestLocalization(options => { options.AddSupportedCultures("de", "en"); });

var supportedCultures = new[] { "en-US", "zh-TW" };
var cultureInfos = supportedCultures.Select(c => new CultureInfo(c)).ToList();

app.UseRequestLocalization(p =>
{
p.DefaultRequestCulture = new RequestCulture("en-US");
p.SupportedCultures = cultureInfos;
p.SupportedUICultures = cultureInfos;
p.RequestCultureProviders.Insert(0, new HeaderRequestCultureProvider());
});
app.UseStaticFiles();
app.UseHttpsRedirection();
app.MapDefaultControllerRoute();
app.UseRouting();

app.Run();
8 changes: 8 additions & 0 deletions i18N/Lab.i18N.WebApi/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
9 changes: 9 additions & 0 deletions i18N/Lab.i18N.WebApi/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
11 changes: 11 additions & 0 deletions i18N/Lab.i18N.WebApi/wwwroot/locales/de/translation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"page": {
"title": "Dies ist ein übersetzter Seitentitel"
},
"about": {
"description": "Dies ist die Beschreibung der About-Seite deiner Homepage.",
"renderedOn": "Diese Datei wurde am {{date, dd.mm.yyyy}} generiert.",
"additionalInformation": "zusätzliche Informationen",
"infoText": "Verwende diesen Bereich um $t(about.additionalInformation) bereitzustellen."
}
}
11 changes: 11 additions & 0 deletions i18N/Lab.i18N.WebApi/wwwroot/locales/en/translation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"page": {
"title": "This is a translated page title"
},
"about": {
"description": "This is the description of your about page.",
"renderedOn": "This page was rendered on {{date, yyyy/mm/dd}}.",
"additionalInformation": "additional information",
"infoText": "Use this area to provide $t(about.additionalInformation)."
}
}
16 changes: 16 additions & 0 deletions i18N/Lab.i18N.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lab.i18N.WebApi", "Lab.i18N.WebApi\Lab.i18N.WebApi.csproj", "{1EFF9ED6-EA59-4C1A-98D9-B019F8355E9B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1EFF9ED6-EA59-4C1A-98D9-B019F8355E9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1EFF9ED6-EA59-4C1A-98D9-B019F8355E9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1EFF9ED6-EA59-4C1A-98D9-B019F8355E9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1EFF9ED6-EA59-4C1A-98D9-B019F8355E9B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

0 comments on commit 433a516

Please sign in to comment.