Headless CMS and Content Managment Hub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

161 lines
4.8 KiB

// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Globalization;
using System.Resources;
using System.Text;
namespace Squidex.Infrastructure.Translations
{
public sealed class ResourcesLocalizer : ILocalizer
{
#if DEBUG
private static readonly MissingKeys MissingKeys = new MissingKeys();
#endif
private readonly ResourceManager resourceManager;
public ResourcesLocalizer(ResourceManager resourceManager)
{
Guard.NotNull(resourceManager, nameof(resourceManager));
this.resourceManager = resourceManager;
}
public (string Result, bool Found) Get(CultureInfo culture, string key, string fallback, object? args = null)
{
Guard.NotNull(culture, nameof(culture));
Guard.NotNullOrEmpty(key, nameof(key));
Guard.NotNull(fallback, nameof(fallback));
var translation = GetCore(culture, key);
if (translation == null)
{
return (fallback, false);
}
if (args != null)
{
var argsType = args.GetType();
var sb = new StringBuilder(translation.Length);
var span = translation.AsSpan();
while (span.Length > 0)
{
var indexOfStart = span.IndexOf('{');
if (indexOfStart < 0)
{
break;
}
indexOfStart++;
var indexOfEnd = span[indexOfStart..].IndexOf('}');
if (indexOfEnd < 0)
{
break;
}
indexOfEnd += indexOfStart;
sb.Append(span.Slice(0, indexOfStart - 1));
var variable = span[indexOfStart..indexOfEnd];
var shouldLower = false;
var shouldUpper = false;
if (variable.Length > 0)
{
if (variable.EndsWith("|lower"))
{
variable = variable[..^6];
shouldLower = true;
}
if (variable.EndsWith("|upper"))
{
variable = variable[..^6];
shouldUpper = true;
}
}
var variableName = variable.ToString();
var variableValue = variableName;
var property = argsType.GetProperty(variableName);
if (property != null)
{
try
{
var value = property.GetValue(args);
if (value != null)
{
variableValue = Convert.ToString(value, culture) ?? variableName;
}
}
catch
{
variableValue = variableName;
}
}
variableValue ??= variableName;
if (variableValue!.Length > 0)
{
if (shouldLower && !char.IsLower(variableValue[0]))
{
sb.Append(char.ToLower(variableValue[0]));
sb.Append(variableValue.AsSpan()[1..]);
}
else if (shouldUpper && !char.IsUpper(variableValue[0]))
{
sb.Append(char.ToUpper(variableValue[0]));
sb.Append(variableValue.AsSpan()[1..]);
}
else
{
sb.Append(variableValue);
}
}
span = span[(indexOfEnd + 1)..];
}
sb.Append(span);
return (sb.ToString(), true);
}
return (translation, true);
}
private string? GetCore(CultureInfo culture, string key)
{
var translation = resourceManager.GetString(key, culture);
if (translation == null)
{
#if DEBUG
MissingKeys.Log(key);
#endif
}
return translation;
}
}
}