Question

Hi I am currently using the asp.net MVC 4 rc with System.Web.Optimization. Since my site needs to be localized according to the user preference I am working with the jquery.globalize plugin.

I would very much want to subclass the ScriptBundle class and determine what files to bundle according to the System.Threading.Thread.CurrentThread.CurrentUICulture. That would look like this:

bundles.Add(new LocalizedScriptBundle("~/bundles/jqueryglobal")
                             .Include("~/Scripts/jquery.globalize/globalize.js")
                             .Include("~/Scripts/jquery.globalize/cultures/globalize.culture.{0}.js", 
                                       () => new object[] { Thread.CurrentThread.CurrentUICulture })
                    ));

For example if the ui culture is "en-GB" I would like the following files to be picked up (minified of course and if possible cached aswell until a script file or the currentui culture changes).

  • "~/Scripts/jquery.globalize/globalize.js"
  • "~/Scripts/jquery.globalize/globalize-en-GB.js" <-- if this file does not exist on the sever file system so fallback to globalize-en.js.

I tried overloading the Include method with something like the following but this wont work because it is not evaluated on request but on startup of the application.

public class LocalizedScriptBundle : ScriptBundle
{
    public LocalizedScriptBundle(string virtualPath)
        : base(virtualPath) { 
    }

    public Bundle Include(string virtualPathMask, Func<object[]> getargs) {
        string virtualPath = string.Format(virtualPathMask, getargs());
        this.Include(virtualPath);
        return this;
    }

}

Thanks

Constantinos

Was it helpful?

Solution

That is correct, bundles should only be configured pre app start. Otherwise in a multi server scenario, if the request for the bundle is routed to a different server other than the one that served the page, the request for the bundle resource would not be found.

Does that make sense? Basically all of your bundles need to be configured and defined in advance, and not dynamically registered on a per request basis.

OTHER TIPS

take a look: https://stackoverflow.com/questions/18509506/search-and-replace-in-javascript-before-bundling

I coded this way for my needs:

public class MultiLanguageBundler : IBundleTransform
{
    public void Process(BundleContext context, BundleResponse bundle)
    {
        var content = new StringBuilder();
        var uicult = Thread.CurrentThread.CurrentUICulture.ToString();

        var localizedstrings = GetFileFullPath(uicult);
        if (!File.Exists(localizedstrings))
        {
            localizedstrings = GetFileFullPath(string.Empty);
        }

        using (var fs = new FileStream(localizedstrings, FileMode.Open, FileAccess.Read))
        {
            var m_streamReader = new StreamReader(fs);
            var str = m_streamReader.ReadToEnd();

            content.Append(str);
            content.AppendLine();
        }

        foreach (var file in bundle.Files)
        {
            var f = file.VirtualFile.Name ?? "";

            if (!f.Contains("localizedstrings"))
            {
                using (var reader = new StreamReader(VirtualPathProvider.OpenFile(file.VirtualFile.VirtualPath)))
                {
                    content.Append(reader.ReadToEnd());
                    content.AppendLine();
                }
            }
        }

        bundle.ContentType = "text/javascript";
        bundle.Content = content.ToString();
    }

    private string GetFileFullPath(string uicult)
    {
        if (uicult.StartsWith("en"))
            uicult = string.Empty;
        else if (!string.IsNullOrEmpty(uicult))
            uicult = ("." + uicult);

        return Kit.ToAbsolutePath(string.Format("~/Scripts/locale/localizedstrings{0}.js", uicult));
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top