Base solution for your next web application
Open Closed

Best Practice - Localization Defined in a separate module #456


User avatar
0
carelearning created

Following the guidelines from module system we have incorporated several of the providers in the module including Localization. See code below.

public class IndividualModule : AbpModule
    {
        public override void PreInitialize()
        {
            Configuration.Authorization.Providers.Add<IndividualAuthorizationProvider>();
            Configuration.Features.Providers.Add<IndividualFeature>();

            Configuration.Localization.Languages.Add(
                new LanguageInfo("en", "English", "famfamfam-flag-us", true));

            Configuration.Localization.Sources.Add(
                   new DictionaryBasedLocalizationSource(
                       Constants.LocalizationSourceName,
                       new XmlEmbeddedFileLocalizationDictionaryProvider(
                           Assembly.GetExecutingAssembly(),
                           Constants.ResourceSource)
                       )
                   );

            Configuration.Navigation.Providers.Add<IndividualNavigationProvider>();
            base.PreInitialize();
        }

        public override void Initialize()
        {
            IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
        }
    }

The question arises when using @L("Individual") in our Razor CSHTML for the AngularJS view it is using the base LocalizationSourceName value . We need to reference the base localization dictionary and that specific module's version too in the same view.

To illustrate createPersonModal.cshtml the first usage line #6 I'd like to say something like @L("CreateNewPerson", "Individual") where the second parameter is the module's dictionary. In contrast line #28 @L("SavingWithThreeDot") remains the same as it needs to reference the base localization dictionary defined in Core.

PS ASP.NET Zero is an awesome Starter Template/Framework and the code is of high quality.


2 Answer(s)
  • User Avatar
    0
    carelearning created

    This workaround involves creating a static method in my module IndividualConstants class and adding a using statement in the view. I am not sure this is the optimal solution but it does work.

    public class IndividualConstants
    {
       public const string LocalizationSourceName = "Individual";
    
       public static ILocalizableString Ls(string name) => new LocalizableString(name, LocalizationSourceName);
       public static string L(string name) => Ls(name).Localize();
    }
    
    @using Individuals
    <div>
        <form class="form-validation" name="createIndividualForm" novalidate role="form">
            <div class="modal-header">
                <h4 class="modal-title">@IndividualConstants.L(IndividualConstants.IndividualCreate)</h4>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label for="Name" class="control-label bold">@L("Name")</label>
     
    
  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    Unfortunately, we can not use dependency injection in razor views. So, we should use static methods. L("...") also does it.

    Your workaround is fine actually. I decided to add a Ls method to localize a string from a given source. See <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/blob/3435a5273657931b3085a0b00c2c606693ca986d/src/Abp.Web.Mvc/Web/Mvc/Views/AbpWebViewPageOfTModel.cs#L106">https://github.com/aspnetboilerplate/as ... el.cs#L106</a>

    You can add these Ls methods to your view base (and remove them when ABP is released and you upgraded).

    Thanks :)