Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Commit

Permalink
Merge pull request #109 from AlexTeixeira/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
AlexTeixeira authored Feb 15, 2021
2 parents 9aa38f5 + 9888640 commit aac274c
Show file tree
Hide file tree
Showing 53 changed files with 1,753 additions and 34 deletions.
6 changes: 6 additions & 0 deletions Askmethat.Aspnet.JsonLocalizer.sln
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Askmethat.Aspnet.JsonLocali
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Askmethat.Aspnet.JsonLocalizer.I18nTestSample", "test\Askmethat.Aspnet.JsonLocalizer.I18nTestSample\Askmethat.Aspnet.JsonLocalizer.I18nTestSample.csproj", "{630D66E9-7DD4-4B6C-891A-F9D829BBE2B9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Askmethat.Aspnet.JsonLocalizer.BlazorWebAssembly", "test\Askmethat.Aspnet.JsonLocalizer.BlazorWebAssembly\Askmethat.Aspnet.JsonLocalizer.BlazorWebAssembly.csproj", "{D4271821-DC98-4FB9-A7C3-107535DFB2F1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -39,6 +41,10 @@ Global
{630D66E9-7DD4-4B6C-891A-F9D829BBE2B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{630D66E9-7DD4-4B6C-891A-F9D829BBE2B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{630D66E9-7DD4-4B6C-891A-F9D829BBE2B9}.Release|Any CPU.Build.0 = Release|Any CPU
{D4271821-DC98-4FB9-A7C3-107535DFB2F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4271821-DC98-4FB9-A7C3-107535DFB2F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4271821-DC98-4FB9-A7C3-107535DFB2F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4271821-DC98-4FB9-A7C3-107535DFB2F1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<Copyright>Copyright 2019 (c) Alexandre TEIXEIRA.</Copyright>
<PackageTags>Json Localizer Globalization netcore netstandard</PackageTags>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>3.1.0</Version>
<Version>3.1.1</Version>
<RepositoryUrl>https://github.com/AlexTeixeira/Askmethat-Aspnet-JsonLocalizer</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
</PropertyGroup>
Expand All @@ -27,6 +27,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.1" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
Expand All @@ -46,7 +47,6 @@
<PropertyGroup Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('$(TargetFramework)', '^netcoreapp\d'))">
<DefineConstants>NETCORE</DefineConstants>
</PropertyGroup>

<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>$(MSBuildProjectName).Test</_Parameter1>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Askmethat.Aspnet.JsonLocalizer.Localizer
{
public class DefaultPluralizationRuleSet : IPluralizationRuleSet
{
private Dictionary<string, Predicate<double>> rules;

public DefaultPluralizationRuleSet()
{
rules = new Dictionary<string, Predicate<double>>();
SetupRules();
}

/// <summary>
/// Override to define any rules for the custom rule set.
/// </summary>
protected virtual void SetupRules()
{
rules.Add(PluralizationConstants.Zero, ValueMatchesZero);
rules.Add(PluralizationConstants.One, ValueMatchesOne);
rules.Add(PluralizationConstants.Other, ValueMatchesOther);
}

protected virtual bool ValueMatchesZero(double value)
{
return value == 0;
}

protected virtual bool ValueMatchesOne(double value)
{
return value == 1.0;
}

protected virtual bool ValueMatchesOther(double value)
{
return value != 1.0;
}

public string GetMatchingPluralizationRule(double count)
{
foreach (var key in rules.Keys)
{
if (rules[key](count))
{
return key;
}
}

//If no match is found, always default to Other.
return PluralizationConstants.Other;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Globalization;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;

namespace Askmethat.Aspnet.JsonLocalizer.Localizer
Expand All @@ -9,6 +10,8 @@ public interface IJsonStringLocalizer: IStringLocalizer
void ClearMemCache(IEnumerable<CultureInfo> culturesToClearFromCache = null);
void ReloadMemCache(IEnumerable<CultureInfo> culturesToClearFromCache = null);
new IStringLocalizer WithCulture(CultureInfo culture);
LocalizedString GetPlural(string key, double count, params object[] arguments);
MarkupString GetHtmlBlazorString(string name, bool shouldTryDefaultCulture = true);
}

public interface IJsonStringLocalizer<out T> : IJsonStringLocalizer
Expand Down
12 changes: 12 additions & 0 deletions Askmethat.Aspnet.JsonLocalizer/Localizer/IPluralizationRuleSet.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Text;

namespace Askmethat.Aspnet.JsonLocalizer.Localizer
{
public interface IPluralizationRuleSet
{
string GetMatchingPluralizationRule(double count);
}
}
72 changes: 70 additions & 2 deletions Askmethat.Aspnet.JsonLocalizer/Localizer/JsonStringLocalizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,34 @@
using System.IO;
using System.Linq;
using Askmethat.Aspnet.JsonLocalizer.JsonOptions;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

namespace Askmethat.Aspnet.JsonLocalizer.Localizer
{
internal class JsonStringLocalizer : JsonStringLocalizerBase, IJsonStringLocalizer
{

#if NETCORE
private readonly IWebHostEnvironment _env;
private readonly IWebHostEnvironment _env;

public JsonStringLocalizer(IOptions<JsonLocalizationOptions> localizationOptions, IWebHostEnvironment env, string baseName
= null) : base(localizationOptions, baseName)
{
_env = env;
resourcesRelativePath = GetJsonRelativePath(_localizationOptions.Value.ResourcesPath);
}
#elif BLAZORASM
private readonly IWebAssemblyHostEnvironment _env;

public JsonStringLocalizer(IOptions<JsonLocalizationOptions> localizationOptions, IWebHostEnvironment env, string baseName
public JsonStringLocalizer(IOptions<JsonLocalizationOptions> localizationOptions, IWebAssemblyHostEnvironment env, string baseName
= null) : base(localizationOptions, baseName)
{
_env = env;
resourcesRelativePath = GetJsonRelativePath(_localizationOptions.Value.ResourcesPath);
}
#else

private readonly IHostingEnvironment _env;

public JsonStringLocalizer(IOptions<JsonLocalizationOptions> localizationOptions, IHostingEnvironment env,
Expand Down Expand Up @@ -80,6 +93,55 @@ private string GetPluralLocalization(string name, string format, object[] argume
return value;
}

public LocalizedString GetPlural(string name, double count, params object[] arguments)
{
bool shouldTryDefaultCulture = true;

if (shouldTryDefaultCulture && !IsUICultureCurrentCulture(CultureInfo.CurrentUICulture))
{
InitJsonFromCulture(CultureInfo.CurrentUICulture);
}
else if (shouldTryDefaultCulture)
{
InitJsonFromCulture(_localizationOptions.Value.DefaultCulture);
}

IPluralizationRuleSet pluralizationRuleSet = GetPluralizationToUse();

var applicableRule = pluralizationRuleSet.GetMatchingPluralizationRule(count);
var nameWithRule = $"{name}.{applicableRule}";

string format = name;

if(localization != null) {
// try get the localization for the specified rule
if (localization.TryGetValue(nameWithRule, out LocalizatedFormat localizedValue))
{
format = localizedValue.Value;
}
else
{
// if no translation was found for that rule, try with the "Other" rule.
var nameWithOtherRule = $"{name}.{PluralizationConstants.Other}";
if (localization.TryGetValue(nameWithOtherRule, out LocalizatedFormat localizedOtherValue))
{
format = localizedOtherValue.Value;
}
else // no pluralized value found. Check out if it's a normal non-pluralized translation
{
format = GetString(name, true);
}
}
}

var argumentsWithCount = arguments.ToList();
argumentsWithCount.Insert(0, count);

// By this point we either found a pluralized or non pluralized translation, or we stick to the received string.
var value = string.Format(format ?? name, argumentsWithCount.ToArray());

return new LocalizedString(name, value, format != null);
}
public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures)
{
InitJsonFromCulture(CultureInfo.CurrentUICulture);
Expand Down Expand Up @@ -150,6 +212,11 @@ private string GetString(string name, bool shouldTryDefaultCulture = true)
return null;
}

public MarkupString GetHtmlBlazorString(string name, bool shouldTryDefaultCulture = true)
{
return new MarkupString(GetString(name, shouldTryDefaultCulture));
}

private void InitJsonFromCulture(CultureInfo cultureInfo)
{
InitJsonStringLocalizer(cultureInfo);
Expand Down Expand Up @@ -208,5 +275,6 @@ public void ReloadMemCache(IEnumerable<CultureInfo> reloadCulturesToCache = null
InitJsonFromCulture(cultureInfo);
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@ internal class JsonStringLocalizerBase
protected string resourcesRelativePath;
protected string currentCulture = string.Empty;
protected ConcurrentDictionary<string, LocalizatedFormat> localization;
protected ConcurrentDictionary<string, IPluralizationRuleSet> pluralizationRuleSets;


public JsonStringLocalizerBase(IOptions<JsonLocalizationOptions> localizationOptions, string baseName = null)
{
_baseName = CleanBaseName(baseName);
_localizationOptions = localizationOptions;
pluralizationRuleSets = new ConcurrentDictionary<string, IPluralizationRuleSet>();

if (_localizationOptions.Value.LocalizationMode == LocalizationMode.I18n && _localizationOptions.Value.UseBaseName)
{
Expand Down Expand Up @@ -74,6 +77,22 @@ protected void GetCultureToUse(CultureInfo cultureToUse)
SetCurrentCultureToCache(_localizationOptions.Value.DefaultCulture);
}
}

protected IPluralizationRuleSet GetPluralizationToUse()
{
IPluralizationRuleSet ruleSet;

if (pluralizationRuleSets.ContainsKey(currentCulture))
{
ruleSet = pluralizationRuleSets[currentCulture];
}
else
{
ruleSet = new DefaultPluralizationRuleSet();
}

return ruleSet;
}
#endregion

#region files initialization
Expand Down Expand Up @@ -180,8 +199,6 @@ private IEnumerable<string> GetMatchingJsonFiles(string jsonPath)
return files;
}



private string TransformNameToPath(string name)
{
return !string.IsNullOrEmpty(name) ? name.Replace(".", Path.DirectorySeparatorChar.ToString()) : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.Extensions.Options;
using System;
using Askmethat.Aspnet.JsonLocalizer.JsonOptions;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

namespace Askmethat.Aspnet.JsonLocalizer.Localizer
{
Expand All @@ -24,7 +25,19 @@ public JsonStringLocalizerFactory(
_env = env;
_localizationOptions = localizationOptions ?? throw new ArgumentNullException(nameof(localizationOptions));
}
#elif BLAZORASM
private readonly IWebAssemblyHostEnvironment _env;

public JsonStringLocalizerFactory(
IWebAssemblyHostEnvironment env,
IOptions<JsonLocalizationOptions> localizationOptions = null)
{
_env = env;
_localizationOptions = localizationOptions ?? throw new ArgumentNullException(nameof(localizationOptions));
}
#else

//private readonly IHostingEnvironment _env;
private readonly IHostingEnvironment _env;

public JsonStringLocalizerFactory(
Expand Down
12 changes: 10 additions & 2 deletions Askmethat.Aspnet.JsonLocalizer/Localizer/JsonStringLocalizerOfT.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Askmethat.Aspnet.JsonLocalizer.JsonOptions;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
Expand All @@ -10,14 +11,21 @@ internal class JsonStringLocalizerOfT<T> : JsonStringLocalizer, IJsonStringLocal
{
#if NETCORE
public JsonStringLocalizerOfT(IOptions<JsonLocalizationOptions> localizationOptions, IWebHostEnvironment env, string baseName
= null) : base(localizationOptions, env, baseName)
= null) : base(localizationOptions, env, ModifyBaseName)
{
}
#elif BLAZORASM
public JsonStringLocalizerOfT(IOptions<JsonLocalizationOptions> localizationOptions, IWebAssemblyHostEnvironment env, string baseName
= null) : base(localizationOptions, env, ModifyBaseName)
{
}
#else
public JsonStringLocalizerOfT(IOptions<JsonLocalizationOptions> localizationOptions, IHostingEnvironment env,
string baseName = null) : base(localizationOptions, env, baseName)
string baseName = null) : base(localizationOptions, env, ModifyBaseName)
{
}
#endif

private static string ModifyBaseName => typeof(T).ToString();
}
}
20 changes: 20 additions & 0 deletions Askmethat.Aspnet.JsonLocalizer/Localizer/PluralizationConstants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Askmethat.Aspnet.JsonLocalizer.Localizer
{
/// <summary>
/// Default pluralization constants as defined in http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules
/// Other custom constants may be defined in a custom implementation.
/// </summary>
public class PluralizationConstants
{
public const string Zero = "Zero";
public const string One = "One";
public const string Two = "Two";
public const string Few = "Few";
public const string Many = "Many";
public const string Other = "Other";
}
}
Loading

0 comments on commit aac274c

Please sign in to comment.