turquoiseowl / i18n

Smart internationalization for ASP.NET
Other
556 stars 155 forks source link

Javascript localization in MVC 5 project #403

Open marth-santi opened 4 years ago

marth-santi commented 4 years ago

Please help I search all issues but see no one encounter the same problem as mine. My project is an MVC 5 with some javascript code behind pages, using jquery ajax to navigate to some cshtml partial component. Localization using Void url scheme in .cshtml and .cs is OK, but when I start using nugget inside string in javascript file ==> the web stuck at my home page, with url still has language postfix ../en or ../vn (behaving like Scheme1), and all elements referred in js file are not displayed / rendered

I dont know how to fix this, having tried: 1/ suspect bundle optimization of js files cause problem ==> set BundleTable.EnableOptimizations = false; ==> no avail 2/ follow this issue #https://github.com/turquoiseowl/i18n/issues/226 ==> change Script.Render() like @advantiss suggests ==> no avail 3/ Change httpCompression in Web.config (suspecting it to be the problem) ==> no avail too

For more info, the home page still render, but without all elements which got referenced in javascript files

marth-santi commented 4 years ago

So I found the problem. The i18n module messes with the bundling process of MVC ==> my Javascript files are cached with the old version and if I change the Js files (add nugget, or anything inside,... ), those files will be completely broken, the view cannot find it.

I havent checked the source code (of i18n). But had anyone encountered and solved this problem ?

vhatuncev commented 4 years ago

@marth-santi here is my solution for this issue. I have a global javascript object which accessible from anywhere on client side. On page load it's initialized only with required on particular page translations words. Then in any javascript code I can access translation object and get required translation. This way will never be affected by cache issue, javascript minification. Also if you need to change translation you will get immediate updates for end users without cache invalidate or new release to production.

Here is my implementation. On server side I have base class for serialization translation objects, as I control which translation goes to the page or control.

public class LangBase
{
        private static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            StringEscapeHandling = StringEscapeHandling.EscapeHtml
        }

        public static HtmlString Serialize(object langObject)
        {
            string serializeObject = JsonConvert.SerializeObject(langObject, JsonSettings);
            HtmlString result = new HtmlString(serializeObject);
            return result;
        }

        public virtual HtmlString ToJson()
        {
            return Serialize(this);
        }
}

This is an example of translation object for specific page

public class ExamplePageTranslation : LangBase
{
        public override HtmlString ToJson()
        {
            var lang = new
            {
                Texts.Name,
                Texts.City
            };

            return Serialize(lang);
        }
}

And finally pass it to page which I need to

<script>
    $(document).ready(function () {
        @{  var lang = new ExamplePageTranslation(); }
        var page = new IndexPage(@lang.ToJson());
    })
</script>