Localization Custom Smart Formatter Bug

No logs. I just get :ns instead of value or whatever I write there. Localization is initializing via VContainer.




img4

namespace Core.Localization
{
    [Serializable]
    public sealed class NumberSeparatorFormatter :
        FormatterBase
    {
        public override string[] DefaultNames => new[] { "ns" };

        private const string DefaultSeparator = ".";
        [SerializeField]
        private string _separator;
        
        public override bool TryEvaluateFormat(IFormattingInfo formattingInfo)
        {
            Debug.LogError("THIS IS NOT BEING INVOKED!");
            var formatterName = formattingInfo.Placeholder?.FormatterName;
            if (string.IsNullOrEmpty(formatterName))
                formatterName = formattingInfo.Format?.RawText;

            foreach (var name in Names)
            {
                if (formatterName != name)
                    continue;
                
                var value = formattingInfo.CurrentValue;
                if (value is not IFormattable formattable)
                    return false;
            
                var formatInfo = new NumberFormatInfo
                { 
                    NumberGroupSeparator = _separator,
                    NumberGroupSizes = new[] { 3 }
                };
                formattingInfo.Write(formattable.ToString("N0", formatInfo));
                return true;
            }
            return false;
        }
        
        public override void OnAfterDeserialize()
        {
            base.OnAfterDeserialize();

            if (string.IsNullOrEmpty(_separator))
                _separator = DefaultSeparator;
        }
    }
}
namespace Core.Localization
{
    public sealed class LocalizationSystem :
        ILocalizationSystem,
        IDisposable,
        IAsyncStartable
    {
        private string _playerPrefsKey;
        
        public event Action<Locale> LocaleChanged;
        public Locale Locale
        {
            get => LocalizationSettings.SelectedLocale;
            set => LocalizationSettings.SelectedLocale = value;
        }
        
        public IReadOnlyList<Locale> Locales => LocalizationSettings.AvailableLocales.Locales;

        async UniTask IAsyncStartable.StartAsync(CancellationToken cancellationToken)
        {
            await LocalizationSettings.InitializationOperation.Task
                .AsUniTask().AttachExternalCancellation(cancellationToken);

            foreach (var selector in LocalizationSettings.StartupLocaleSelectors)
            {
                if (selector is not PlayerPrefLocaleSelector playerPrefLocaleSelector)
                    continue;
                
                _playerPrefsKey = playerPrefLocaleSelector.PlayerPreferenceKey;
            }

            LocalizationSettings.SelectedLocaleChanged += OnSelectedLocaleChanged;
        }
        void IDisposable.Dispose()
        {
            LocalizationSettings.SelectedLocaleChanged -= OnSelectedLocaleChanged;
        }

        private void OnSelectedLocaleChanged(Locale locale)
        {
            if (!string.IsNullOrWhiteSpace(_playerPrefsKey))
                PlayerPrefs.SetString(_playerPrefsKey, locale.Identifier.Code);
            
            LocaleChanged?.Invoke(locale);
        }
    }
}

Did you add your formatter to the localization settings under string database? Try moving it above the other formatters. It will try to match the formatter by name but it also looks for implicit matches where the name is not specified, it may be thinking that NS is an argument for a formatter and not a name.

Edit: Nevermind I can see from the screenshot you did. I’ll take a closer look tomorrow and see if I can see whats going wrong.

Try {value:ns()}

It’s working with {value:ns()}

My mistake. The documentation mentions this in the “Example Smart String”. Thanks for the solution!

img1