2009-08-12 72 views
10

逸出Freemarker的模板,我們可以使用轉義指令的逃逸自動應用到包含塊內的所有插值:默認在Freemarker的

<#escape x as x?html> 
    <#-- name is escaped as html --> 
    Hallo, ${name} 
</#escape> 

有沒有一種方法以編程方式達到類似的效果,定義了默認轉義應用於模板中的所有插值,包括那些外部轉義指令?

謝謝。

回答

2

有一個解決方案,雖然它不是微不足道的。您可以創建一個特殊的TemplateLoader來封裝其他模板加載器,並在模板源文本的序言中注入#escape x作爲x?html>,並添加爲它的結尾。

明顯的缺點: - 列數在第一行會被甩出 - 如果您的模板與< #ftl>聲明開始,你需要在它後面插入< #escape>。

5

爲了詳細說明阿提拉的回答是:你可以使用一個類像this one,然後換你的模板加載器是這樣的:

final TemplateLoader templateLoader = new ClassTemplateLoader(this.getClass(), templatePath) { 
    /** 
    * Replaces the normal template reader with something that changes the default 
    * escaping to HTML as to avoid XSS attacks. 
    */ 
    @Override 
    public Reader getReader(Object templateSource, String encoding) throws IOException { 
    return new WrappingReader(super.getReader(templateSource, encoding), "<#escape x as x?html>", "</#escape>"); 
    } 
}; 

如果不包括增加的部分換行符你沒有得到的行編號問題。儘管如此,您無法使用<#ftl>/[#ftl]。

+0

彼得鏈接WrappingReader類不工作了。新位置:http://sourceforge.net/p/metadata-net/code/HEAD/tree/shared/trunk/util/src/main/java/au/edu/uq/itee/maenad/util/WrappingReader。 java – 2013-09-26 14:41:02

+0

@StefanHaberl:我更新了答案 - 謝謝。 – 2013-09-27 04:41:32

1

實際上您並不需要WrappingReader來添加換碼。你可以在任何TemplateLoader周圍創建一個裝飾器,在模板中讀入一個String,在escapes中包裝模板文本,然後返回一個讀取結果String的StringReader。要看看如何完成看看here。我發現的唯一問題是,如果你使用這種方法並從類路徑中包含spring.ftl宏,它們將會炸燬,因爲它們在頂部有一個< #ftl>聲明。但是,您可以簡單地將spring.ftl複製到您的模板路徑中,並刪除聲明(以及所有轉義指令,因爲您將默認轉義)。

2

如果您正在使用< #include parse = false ... />在模板中包含HTML,則鏈接中的建議TemplateLoaders需要稍微調整。

此外,您需要複製spring.ftl並使用您自己的副本與< #ftl ..>指令頂部刪除像湯姆說。

以下效果很好,儘管有點粗糙(使用番石榴過度公地1-10)

@Override 
public Reader getReader(Object pTemplateSource, String pEncoding) throws IOException { 
    Reader tReader = delegate.getReader(pTemplateSource, pEncoding); 
    try { 
     String tTemplateText = CharStreams.toString(tReader); 

     //only include files ending with "ftl", as we may have some parse=false on included html files 
     if (pTemplateSource.toString().endsWith("ftl")) { 
      return new StringReader(ESCAPE_PREFIX + tTemplateText + ESCAPE_SUFFIX); 
     } 
     return new StringReader(tTemplateText); 
    } finally { 
     Closeables.closeQuietly(tReader); 
    } 
} 
3

由於2.3.24每個模板具有相關聯的對象freemarker.core.OutputFormat,指定是否以及如何${...}(和#{...})逃脫。提供HTML,XML和RTF的OuputFormat開箱即用,但您也可以定義自己的格式。當默認選擇OutputFormat轉義時,則可以像${foo?no_esc}那樣顯式地防止轉義。

有幾種方法可以將模板與您想要的OutputFormat相關聯。對於HTML和XML轉義,推薦的方法是將recognize_standard_file_extensions配置設置設置爲true,然後將ftlh文件擴展名用於HTML,ftlx文件擴展名用於XML模板。您還可以使用template_configurers設置將OutputFormat -s與基於任意模板名稱(模板路徑)模式的模板相關聯。最後同樣重要的是,您可以設置全局默認輸出格式,如configuration.setOutputFormat(HTMLOutputFormat.INSTANCE)。您也可以覆蓋模板頂部的輸出格式<#ftl output_format='HTML'>,儘管它應該很少使用。

相關文檔頁數:http://freemarker.org/docs/dgui_misc_autoescaping.htmlhttp://freemarker.org/docs/pgui_config_outputformatsautoesc.html