5

Tôi hiện đang cố thiết lập dự án để triển khai bản địa hóa trên tệp javascript (như được mô tả here) nhưng đồng thời tôi muốn nhóm và rút gọn javascript trong dự án. Tôi đã làm theo cả hướng dẫn về đóng gói và rút gọn hereTrình xử lý HTTP và gói javascript trong VS 2012

Tôi có thể làm việc riêng biệt, nhưng khi tôi cố gắng làm cho chúng hoạt động cùng nhau, tôi không thể làm cho bản địa hóa hoạt động bình thường. Tôi nghĩ rằng điều này là bởi vì bundling tạo ra nó xử lý đường riêng của nó cho gói javascript/minified nó tạo ra, vì vậy httpHandler tôi đã định nghĩa trong webconfig bị bỏ qua. Tôi tiếp tục nhận được lỗi javascript nói rằng "CustomTranslate không được xác định".

Tôi đang cố gắng làm điều này vì chúng tôi đang xây dựng một số điều khiển bằng ExtJS, nhưng chúng tôi cần có khả năng áp dụng bản địa hóa cho các điều khiển đó. Bất kỳ trợ giúp/ý tưởng về cách tôi có thể làm cho họ làm việc cùng nhau sẽ được đánh giá cao.

Tôi không sử dụng MVC, nhưng làm điều này trong asp.net trong Visual Studio 2012.

Đây là mã của tôi:

BundleConfig.cs

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")); 

     } 
    } 
}  

web.config :

<globalization uiCulture="auto" /> 
<httpHandlers> 
    <add verb="*" path="/bundles/ExtJS.axd" type="TranslationTest.ScriptTranslator, TranslationTest" /> 
</httpHandlers> 

Mặc định.aspx

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TranslationTest._Default" %> 

<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent"> 
    <script src="/bundles/ExtJS.axd"></script> 
</asp:Content>  

TestForm.js:

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); 


}); 

Hiện nay FirstName, LastName, vv đều được lưu trữ trong các tập tin tài nguyên, như trong ví dụ liên kết ở trên.

ScriptTranslator.cs

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 && context.Request.Headers["Accept-encoding"].Contains(encoding); 
     } 

     private static void SetEncoding(string encoding, HttpContext context) 
     { 
      context.Response.AppendHeader("Content-encoding", encoding); 
     } 

     #endregion 

    } 
} 

global.asax.cs

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(); 
     } 
    } 
} 

Tôi hy vọng tôi đã đề cập tất cả mọi thứ, nhưng xin vui lòng cho tôi biết nếu có bất cứ điều gì thiếu. Cảm ơn trước!!

+0

Btw, có lẽ cũng đáng nói mà tôi cũng đã cố gắng làm cho kịch bản dịch của tôi thực hiện IRouteHandler quá, nhưng không có nhiều may mắn đi xuống đường mà một trong hai. – Paul

Trả lời

5

Ok, tôi đã thiết lập mọi thứ trong ví dụ của bạn và tôi đã làm việc đó nhưng bạn cần sử dụng giao diện IBundleTransform. Chi tiết về mọi thứ tôi đã làm được đăng bên dưới ..

Tôi phải tạo một lớp để xử lý việc chuyển đổi gói (tức là bản dịch) thay vì cho phép hành vi mặc định.

public class JsLocalizationTransform : IBundleTransform 
    { 
     public JsLocalizationTransform(){} 

     #region IBundleTransform Members 

     public void Process(BundleContext context, BundleResponse response) 
     { 
      string translated = TranslateScript(response.Content); 

      response.Content = translated; 
     } 

     #endregion 

     #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; 
     } 
     #endregion 

    } 

Sau đó, trong phương pháp BundleConfig.RegisterBundles bạn cần để tạo ra và thêm bó như thế này:

var extjsBundle = new Bundle("~/bundles/ExtJS").Include("~/Scripts/ExtJS/ext-all.js", "~/Scripts/ExtJS/TestForm.js"); 
    extjsBundle.Transforms.Clear(); 
    extjsBundle.Transforms.Add(new JsLocalizationTransform()); 
    extjsBundle.Transforms.Add(new JsMinify()); 
    bundles.Add(extjsBundle); 

tôi sau đó có thể loại bỏ các HttpHandler từ web.config như đó được cấu hình tự động thông qua các bundler. Tôi cũng phải thực hiện một số thay đổi đối với phương thức Application_Start trong global.asax.cs

void Application_Start(object sender, EventArgs e) 
     { 
      //Microsoft.Web.Optimization.BundleTable.Bundles.EnableDefaultBundles(); 
      BundleTable.EnableOptimizations = true; //Added this line.. 
      BundleConfig.RegisterBundles(System.Web.Optimization.BundleTable.Bundles); 
      AuthConfig.RegisterOpenAuth(); 
     } 

Bởi vì lớp JSLocalisationTransform là xử lý việc chuyển đổi gói và dịch thuật, tôi hoàn toàn loại bỏ các lớp ScriptTranslator.

Hy vọng điều đó sẽ hữu ích.

+0

Perfect, nhờ Grant – Paul

Các vấn đề liên quan