Note that there are some explanatory texts on larger screens.

plurals
  1. POHTTP handlers and javascript bundling in VS 2012
    primarykey
    data
    text
    <p>I am currently trying to setup a project to implement localization on javascript files (as described <a href="http://madskristensen.net/post/Localize-text-in-JavaScript-files-in-ASPNET.aspx" rel="nofollow">here</a>) but at the same time I'd like to bundle and minify the javascript in the project. I followed a tutorial on bundling and minification <a href="http://msdn.microsoft.com/en-us/vs11trainingcourse_aspnetandvisualstudio_topic5#_Toc319053054" rel="nofollow">here</a></p> <p>I have been able to get both working separately, but when I try to get them working together I cannot get the localisation working properly. I think this is because bundling creates it's own route handling for the bundled/minified javascript it generates, so the httpHandler I have defined in the webconfig gets ignored. I keep getting javascript errors saying "CustomTranslate is not defined".</p> <p>I am trying to do this because we are building a number of controls using ExtJS, but we need to be able to apply localisation to those controls. Any help/ideas on how I can get them to work together would be appreciated.</p> <p>I am <strong>not</strong> using MVC, but doing this in asp.net in Visual Studio 2012.</p> <p>Here is my code:</p> <p>BundleConfig.cs</p> <pre><code>namespace TranslationTest { public class BundleConfig { public static void RegisterBundles(BundleCollection bundles) { //default bundles addeed here... bundles.Add(new ScriptBundle("~/bundles/ExtJS.axd").Include("~/Scripts/ExtJS/ext-all.js", "~/Scripts/ExtJS/TestForm.js")); } } } </code></pre> <p>web.config: </p> <pre><code>&lt;globalization uiCulture="auto" /&gt; &lt;httpHandlers&gt; &lt;add verb="*" path="/bundles/ExtJS.axd" type="TranslationTest.ScriptTranslator, TranslationTest" /&gt; &lt;/httpHandlers&gt; </code></pre> <p>Default.aspx</p> <pre><code>&lt;%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TranslationTest._Default" %&gt; &lt;asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent"&gt; &lt;script src="/bundles/ExtJS.axd"&gt;&lt;/script&gt; &lt;/asp:Content&gt; </code></pre> <p>TestForm.js: </p> <pre><code>Ext.require([ 'Ext.form.*', 'Ext.layout.container.Column', 'Ext.tab.Panel' ]); Ext.onReady(function () { Ext.QuickTips.init(); var bd = Ext.getBody(); bd.createChild({ tag: 'h2', html: 'Form 1' }); var simple = Ext.create('Ext.form.Panel', { url: 'save-form.php', frame: true, title: 'Simple Form', bodyStyle: 'padding:5px 5px 0', width: 350, fieldDefaults: { msgTarget: 'side', labelWidth: 75 }, defaultType: 'textfield', defaults: { anchor: '100%' }, items: [{ fieldLabel: CustomTranslate(FirstName), name: 'first', allowBlank: false }, { fieldLabel: CustomTranslate(LastName), name: 'last' }, { fieldLabel: CustomTranslate(Company), name: 'company' }, { fieldLabel: CustomTranslate(Email), name: 'email', vtype: 'email' }, { xtype: 'timefield', fieldLabel: CustomTranslate(Time), name: 'time', minValue: '8:00am', maxValue: '6:00pm' }], buttons: [{ text: CustomTranslate(Save) }, { text: CustomTranslate(Cancel) }] }); simple.render(document.body); }); </code></pre> <p>Currently the FirstName, LastName, etc are all stored in resource files, as in the linked example above.</p> <p>ScriptTranslator.cs</p> <pre><code>namespace TranslationTest { public class ScriptTranslator : IHttpHandler { #region IHttpHandler Members public bool IsReusable { get { return false; } } public void ProcessRequest(HttpContext context) { string relativePath = context.Request.AppRelativeCurrentExecutionFilePath.Replace(".axd", string.Empty); string absolutePath = context.Server.MapPath(relativePath); string script = ReadFile(absolutePath); string translated = TranslateScript(script); context.Response.Write(translated); Compress(context); SetHeadersAndCache(absolutePath, context); } #endregion private void SetHeadersAndCache(string file, HttpContext context) { context.Response.AddFileDependency(file); context.Response.Cache.VaryByHeaders["Accept-Language"] = true; context.Response.Cache.VaryByHeaders["Accept-Encoding"] = true; context.Response.Cache.SetLastModifiedFromFileDependencies(); context.Response.Cache.SetExpires(DateTime.Now.AddDays(7)); context.Response.Cache.SetValidUntilExpires(true); context.Response.Cache.SetCacheability(HttpCacheability.Public); } #region Localization private static Regex REGEX = new Regex(@"CustomTranslate\(([^\))]*)\)", RegexOptions.Singleline | RegexOptions.Compiled); private string TranslateScript(string text) { MatchCollection matches = REGEX.Matches(text); ResourceManager manager = new ResourceManager(typeof(TranslationTest.App_GlobalResources.text)); foreach (Match match in matches) { object obj = manager.GetObject(match.Groups[1].Value); if (obj != null) { text = text.Replace(match.Value, CleanText(obj.ToString())); } } return text; } private static string CleanText(string text) { text = text.Replace("'", "\\'"); text = text.Replace("\\", "\\\\"); return text; } private static string ReadFile(string absolutePath) { if (File.Exists(absolutePath)) { using (StreamReader reader = new StreamReader(absolutePath)) { return reader.ReadToEnd(); } } return null; } #endregion #region Compression private const string GZIP = "gzip"; private const string DEFLATE = "deflate"; private static void Compress(HttpContext context) { if (IsEncodingAccepted(DEFLATE, context)) { context.Response.Filter = new DeflateStream(context.Response.Filter, CompressionMode.Compress); SetEncoding(DEFLATE, context); } else if (IsEncodingAccepted(GZIP, context)) { context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress); SetEncoding(GZIP, context); } } private static bool IsEncodingAccepted(string encoding, HttpContext context) { return context.Request.Headers["Accept-encoding"] != null &amp;&amp; context.Request.Headers["Accept-encoding"].Contains(encoding); } private static void SetEncoding(string encoding, HttpContext context) { context.Response.AppendHeader("Content-encoding", encoding); } #endregion } } </code></pre> <p>global.asax.cs</p> <pre><code>namespace TranslationTest { public class Global : HttpApplication { void Application_Start(object sender, EventArgs e) { Microsoft.Web.Optimization.BundleTable.Bundles.EnableDefaultBundles(); BundleConfig.RegisterBundles(System.Web.Optimization.BundleTable.Bundles); AuthConfig.RegisterOpenAuth(); } } } </code></pre> <p>I hope I've covered everything, but please let me know if there's anything missing. Thanks in advance!!</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload