在前面的教程 CodeSmith 使用教程(3): 自動生成 Yii Framework ActiveRecord 我們使用了主,從模板來實(shí)現(xiàn)了從數(shù)據(jù)庫為 Yii Framework 生成多個表的 ActiveRecord 類定義,中 CodeSmith 項(xiàng)目中通過主模板和從模板的配合可以實(shí)現(xiàn)復(fù)雜的代碼生成過程,主模板和從模板的關(guān)系有點(diǎn)類似主程序和子函數(shù)的關(guān)系。使用主-從模板的基本步驟如下:
<%@ Register Name="Header" Template="Header.cst"
MergeProperties="True" ExcludeProperties="IncludeMeta" %>
Name:子模板在主模板中的類型名稱,在主要模板中可以通過該類型創(chuàng)建子模板的實(shí)例 Template: 子模板文件名 MergeProperties: 是否需要把子模板中定義的屬性:“合并”到主模板中。缺省為 False ExcludeProperties: 如果子模板的屬性合并到主模板中時需要排除的屬性列表,以逗號分隔。
MergeProperties=”True” 可以把從模板中的屬性合并到主模板中,如果從模板需要引用主模板的屬性,比如主模板中定義了服務(wù)器地址,在多個子模板中都需要引用這個屬性,此時可以通過復(fù)制父模板屬性 CopyPropertiesTo 來實(shí)現(xiàn):
// instantiate the sub-template
Header header = this.Create<Header>();
// copy all properties with matching name and type to the sub-template instance
this.CopyPropertiesTo(header);
CopyPropertiesTo 方法比較主模板中定義的屬性和子模板中定義的屬性,如果發(fā)現(xiàn)從模板中定義的屬性和主模板中定義的屬性名稱類型相同(匹配)則把主模板中屬性值復(fù)制到子模板中。
在主模板中要創(chuàng)建子模板的實(shí)例,可以直接通過 Create 方法
// instantiate the sub-template
Header header = this.Create<Header>();
// include the meta tag
header.IncludeMeta = true;
Create 中的 Header 為注冊子模板時 Name 來定義的類型,通過 Create 創(chuàng)建子模板的實(shí)例后,就直接可以通過該實(shí)例的屬性來訪問子模板中的屬性,比如上面代碼中 IncludeMeta 為子模板中定義的一個屬性。
創(chuàng)建好子模板的實(shí)例,設(shè)置好子模板的屬性,在主模板中就可以讓子模板輸出結(jié)果,有幾種方法可以從子模板輸出內(nèi)容。
第一種是把子模板生成的結(jié)果直接插入到主模板中
// instantiate the sub-template.
Header header = this.Create<Header>();
// render the sub-template to the current output stream.
header.Render(this.Response);
第二種方法是把結(jié)果輸出到單獨(dú)的文件中:
// instantiate the sub-template.
Header header = this.Create<Header>();
// render the sub-template to a separate file.
header.RenderToFile("Somefile.txt");
具體的例子可以參見 CodeSmith 使用教程(3): 自動生成 Yii Framework ActiveRecord