2010-12-03 59 views
3

我想嘗試讓NVelocity自動對我的MonoRail應用程序中的某些字符串進行HTML編碼。自動HTML編碼NVelocity輸出(EventCartridge&ReferenceInsert)

我查看了NVelocity的源代碼,發現EventCartridge,這似乎是一個你可以插入來改變各種行爲的類。

特別是這個類有一個ReferenceInsert方法,這似乎正是我想要的。它基本上在引用的值(例如$ foobar)被輸出之前被調用,並允許您修改結果。

我不能解決的是我如何配置NVelocity/MonoRail NVelocity視圖引擎來使用我的實現?

Velocity docs建議velocity.properties可以包含用於添加特定事件處理程序的條目,但在NVelocity源代碼中找不到此配置的任何位置。

任何幫助非常感謝!


編輯:(!概念證明這樣不生產代碼)一個簡單的測試,顯示這方面的工作

private VelocityEngine _velocityEngine; 
private VelocityContext _velocityContext; 

[SetUp] 
public void Setup() 
{ 
    _velocityEngine = new VelocityEngine(); 
    _velocityEngine.Init(); 

    // creates the context... 
    _velocityContext = new VelocityContext(); 

    // attach a new event cartridge 
    _velocityContext.AttachEventCartridge(new EventCartridge()); 

    // add our custom handler to the ReferenceInsertion event 
    _velocityContext.EventCartridge.ReferenceInsertion += EventCartridge_ReferenceInsertion; 
} 

[Test] 
public void EncodeReference() 
{ 
    _velocityContext.Put("thisShouldBeEncoded", "<p>This \"should\" be 'encoded'</p>"); 

    var writer = new StringWriter(); 

    var result = _velocityEngine.Evaluate(_velocityContext, writer, "HtmlEncodingEventCartridgeTestFixture.EncodeReference", @"<p>This ""shouldn't"" be encoded.</p> $thisShouldBeEncoded"); 

    Assert.IsTrue(result, "Evaluation returned failure"); 
    Assert.AreEqual(@"<p>This ""shouldn't"" be encoded.</p> &lt;p&gt;This &quot;should&quot; be &#39;encoded&#39;&lt;/p&gt;", writer.ToString()); 
} 

private static void EventCartridge_ReferenceInsertion(object sender, ReferenceInsertionEventArgs e) 
{ 
    var originalString = e.OriginalValue as string; 

    if (originalString == null) return; 

    e.NewValue = HtmlEncode(originalString); 
} 

private static string HtmlEncode(string value) 
{ 
    return value 
     .Replace("&", "&amp;") 
     .Replace("<", "&lt;") 
     .Replace(">", "&gt;") 
     .Replace("\"", "&quot;") 
     .Replace("'", "&#39;"); // &apos; does not work in IE 
} 

回答

2

嘗試連接新EventCartridge到VelocityContext。參見these tests

既然您已確認此方法有效,請從Castle.MonoRail.Framework.Views.NVelocity.NVelocityEngine繼承,覆蓋BeforeMerge並在那裏設置EventCartridge和事件。然後配置MonoRail以使用此自定義視圖引擎。

+0

感謝您回覆Mauricio。我不認爲你知道如何獲得MonoRail視圖引擎中使用的速度上下文的引用?或者如果有一種方法,我可以全局配置MonoRail爲所有頁面使用我的EventCartridge? – 2010-12-04 16:00:42