首頁  >  文章  >  php教程  >  FreeMarker排列(配置)

FreeMarker排列(配置)

高洛峰
高洛峰原創
2017-01-05 13:25:362180瀏覽

p> 基礎

Configuration 是一個存放應用層級(application level)公共配置訊息,以及模版(Template)可使用的全域共享變數的物件。同時它還負責模版(Template)實例的建立以及快取。 Configuration 其實是freemarker.template.Configuration 物件的實例,使用其建構子建立。通常會應用使用一個共享的單實例Configuration 物件。

Configuration 物件可被Template 物件的方法使用,每個模版實例都關聯與一個Configuration 實例,它是透過Template 的建構子被關聯進去的,通常是你使用這個方法來Configuration.getTemplate 取得模版物件的。

共享變數

共享變數是那些定義給所有模版(Template)使用的變數。你可以透過configuration物件的setSharedVariable 方法來新增共享變數。

Configuration cfg = new Configuration(); ... cfg.setSharedVariable("wrap", new WrapDirective()); cfg.setSharedVariable("company", "Foo Inc."); // Using ObjectWr.PERP.
所有與該configuration 物件關聯的模版實例都可以透過取得to_upper 轉換器,company 來取得字串,因此你不需要再一次次的往root 中新增這些變數了。如果你往root 新增同名的變量,那麼你新加入的變數將會覆蓋先前的共享變數。

警告!

如果configuration 物件被多線程調用,那麼不要使用TemplateModel 實作類別作為共享變量,因為他們是非線程安全的,例如基於servlet 的web 站點就是這種情況。

Configuration 物件在初始化時已經包含一些共享轉換器變數:

名字類別

name class capture_output freemarker.template.utility.CaptureOutput compress freemarker.template.utility.Compress html_e. .utility.NormalizeNewlines xml_escape freemarker.template.utility.XmlEscape 

配置參數

配置參數是那些可以影響FreeMarker 運作行為的那些命名參數。例如locale,number_format。

配置參數儲存在Configuration實例中,它可以被模版實例(Template)修改。例如,你在Configuration中設定了locale等於"en_US",那麼所有的模版物件都會使用,"en_US"除非你在單一模版實例中利用setLocale方法修改了預設設定。因此configuration設定的參數可以當作是預設參數,它可以被Template一級設定的參數覆蓋,而它們兩者設定的參數資訊又可以被環境中設定的參數所覆蓋(也就是模版檔案指令設定的)如下:

${1.2}${1.2}

這種調用方式你可以想像成3 個層(配置物件層,模版層,運行環境層)下面表格中顯示了每一層對於參數的設定:

Setting A Setting B Setting C Setting D Setting E Setting F Layer 3:Environment 1 - - 1 - - Layer 2:Template 2 2 - - 2 - Layer 1:Configuration 3 3 3 3 - -

那麼配置參數的最終結果分別是:A = 1, B = 2, C = 3, D = 1, E = 2.而F 參數很可能就是null。

如果要查詢可設定的參數列表,你可以查閱FreeMarker API 文件的以下兩個部分:

所有層的配置


freemarker.core.Configurable.setSetting(String, String)

Coniguration 層的配置配置

Coniguration 層的配置。 freemarker.template.Configuration.setSetting(String,String)


載入範本

模版載入器

模版載入器是基於抽象路徑("index.ftl"或"products/catalog.的那些對象,而究竟載入何種資源(目錄中的檔案資料還是資料庫中的資料)取決於具體的載入器實作。當你呼叫cfg.getTemplate 時,FreeMarker 將會詢問你先前配置給Configuration 物件的模版載入器,有該模版載入器負責檔案的載入。

內建的模版載入器

你可以用以下三個方法來設定模版載入的三種方式

void setDirectoryForTemplateLoading(File dir);

void setClassForTemplate, Class setge,g或

void setServletContextForTemplateLoading(Object servletContext, String path);

以上第一種方式顯示的指定了一個檔案系統中的目錄,FreeMarker 將會在此目錄記載模版,不用說,此目錄必須存在,否在會拋出異常。

第二種方式以一個Class作為一個輸入參數,當你想使用ClassLoader的方式來加載模版的時候,你就可以使用這種方式,這種方式將會調用來尋找模版文件,同時這種模版加載的方式要比前一種穩定一些尤其是在生產系統中。你可以很容易的把資源文件,以及圖標等打包到.jar 文件中。

第三種方式把web 應用的上下文以及基底路徑(相對與WEN-INF 的父路進來說)當作參數。該種方式的模版載入器將會從web 應用上下文種載入模版。

從多個位置加載模版

如果你想從多個位置加載模版的話,你可以分別創建與不同位置對應的單個模版加載器,然後把它們包裹到一個名叫MultiTemplateLoader透過方法setTemplateLoader(TemplateLoader loader)把其設定給Configuration 對象,以下有一個從兩個不同位置載入模版的例子:

import freemarker.cache.*; // template loaders live in this package ... FileTemplateLoader ftl1 = new FileTemplateLoader(new File("/tmp/templates")); FileTemplateLoader ftl2 = new FileTemplateLoader(new File("/usr/data/templates")); ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), ""); TemplateLoader ctl = new ClassTemplateLoader(getClass(), ""); TemplateLoader [] loaders = new TemplateLoader[] { ftl1, ftl2, ctl }; MultiTemplateLoader mtl = new MultiTemplateLoader(loaders); cfg.setTemplateLoader(mtl); 

FreeMarker 將會先在路徑/tmp/templates/tmp/templates沒有找到那麼回到路徑/usr/data/templates中搜索,如果還沒找到,那麼則會嘗試用class-loader的方式載入。

從其他資源中取得模版檔案

如果在這些內建的模版載入器中沒有一個符合你的要求,那麼你可以自己自訂一個模版載入器,只需要實作freemarker.cache.TemplateLoader 介面就可以了,然後透過方法setTemplateLoader(TemplateLoader loader)把其傳遞給Configuration物件。

快取模版

FreeMarker快取模版的意思是,當你透過getTemplate方法取得一個模版的時候,FreeMarker不僅會返回一個Template對象,而且會快取該對象,當你下一次以相同的路徑請求模版的時候,它就會傳回快取中的模版物件。如果你改變了模版文件,那麼當你下次取得模版的時候,FreeMarker會自動重新載入,重新解析模版。雖然如此,但是如果直接判斷一個檔案是否修改過是一個耗時的操作,那麼FreeMarker 在Configuration 物件層級提供了一個設定參數「update delay」。這個參數的意思是FreeMarker多久去判斷一次模版的版本,預設設定是5秒鐘,也就是每個5秒就會判斷模版是否經過修改,如果你想即時的判斷,那麼設定該參數為0 。另外一點要注意,並不是所有的載入器都支援這種判斷方式,舉例來說基於class-loader 的模版載入器就不會發現你修改過模版檔案。

對於刪除快取中的模版FreeMarker 是這麼做的,你可以使用Configuration 物件方法clearTemplateCache 以手工的方式清楚快取中的模版物件。而實際上快取部分可以作為一個組成加入到FreeMarker 中(也就是它可以使用第三方快取方案)你可以透過設定cache_storage 這個參數來實現。對大多數開發者來FreeMarker 自帶的freemarker.cache.MruCacheStorage 實作已經足夠了。這個快取使用2 個等級的Most Recently Used(最近最多使用)策略。在第一個級別,所有的快取條目都是使用強引用(strongly referenced:條目並不會被JVM 所清楚,與其相對的弱引用softly reference)直到達到最大時間,那些最近最少使用的條目就會被遷移到二級快取。在這個等級條目都是使用弱引用直到達到過期。若引用與強引用的區域的大小是可以在建構函式中設定的,例如你想把強引用區域設為20,弱引用區域設定為250,那你可以使用以下程式碼:

cfg.setCacheStorage(new freemarker.cache.MruCacheStorage(20, 250))

由於MruCacheStorage 是預設的快取實現,那麼你也可以這樣設定:

cfg.setSetting(Configuration.CACHE_STORAGE_KEYEY"strong:20, softration

";

當你建立一個新的Configuration時,其預設使用MruCacheStorage快取實作且預設的值maxStrongSize等於0,maxSoftSize等於Integer.MAX_VALUE(也就是理論最大值)。但是對於高負載的系統來說,我們建議maxStrongSize 設定成一個非0 的數值,不然會導致頻繁的重新加載,重新解析模版。

異常處理

可能產生的異常

FreeMarker 產生的異常一般可歸以下幾類:

FreeMarker 初始化階段產生的異常: 通常在你的應用中僅需要初始化FreeMarker 一次,而當在這個時間段類別產生的異常就叫做初始化異常。

載入解析模版期的異常:當你透過Configuration.getTemplate()方法取得模版的時候(如果模版之前沒有被快取),將會產生兩類異常:

IOException:由於模版沒有找到,或在讀取模版的時候發生其他的IO異常,例如你沒有讀取該檔案的權限等等;freemarker.core.ParseException 由於模版檔案的語法使用不正確;

執行期間的例外:當你呼叫Template.process(...)方法的時候,會拋出兩類異常:

I​​OException 往輸出寫資料時發生的錯誤;freemarker.template.TemplatException其他運行期產生的異常,例如一個最常見的錯誤就是模版引用了一個不存在的變數;

更多FreeMarker配置(Configuration)相關文章請關注PHP中文網!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn