C&C++的模板引擎相對比較少,比較有名的是ClearSilver
和Teng
,他們功能都比較強大,我需要一個輕量級的模板引擎Ctemplate
ctemplate的設計哲學是輕量級,快速,且邏輯和介面分離,因此和ClearSilver和Teng是有一些差異的。比如Ctemplate就沒有模板函數,沒有條件判斷和迴圈語句(當然,它可以通過變通的方式來實現)。
1.Ctemplate介紹
ctemplate大體上分為兩個部分,一部分是模板,另一部分是資料字典。模板定義了介面展現的形式(V),資料字典就是填充模板的資料(M),你自己寫商務邏輯去控制介面展現(C),典型的MVC模型。
ctemplate模板中有四中標記,對應的資料字典也有不同的處理方式:
- 變數,{{變數名}},用兩個大括弧包含的就是變數名,在c++代碼中,可以對變數賦值,任何類型的值都可以(如字元,整數,日期等)。
- 片斷,{{#片斷名}},片斷在資料字典中表現為一個子字典,字典是可以分級的,根字典下面有多級子字典。片斷可以處理條件判斷和迴圈。
- 包含,{{>模板名}}包含指的是一個模板可以包含其他模板,對應的也是一個字字典。
- 注釋,{{!注釋名}},包含注釋。
一份示範了完整四種標記的例子如下,
- <!--ctexample.tpl-->
- <
html
>
- <
head
>
-
<
title
>
{{NAME}}
</
title
>
- </
head
>
- {{!This is a example of template.}}
- <
body
>
- Hello {{NAME}},
- You have just won ${{VALUE}}!
- <
table
>
- {{#IN_TABLE}}
- <
tr
>
-
<
td
>
{{ITEM}}
</
td
>
-
<
td
>
{{TAXED_VALUE}}
</
td
>
- </
tr
>
- {{/IN_TABLE}}
- </
table
>
- {{
>
INCLUDED_TEMPLATE}}
- </
body
>
- </
html
>
- <!--ctinclude.tpl-->
-
<
div
>
- {{INCLUDE_VAR}}
- </
div
>
c++代碼如下
- #include <stdlib.h>
- #include <string>
- #include <iostream>
- #include <google/template.h>
- int
main(
int
argc,
char
** argv) {
- TemplateDictionary dict(
"example"
);
- dict.SetValue(
"NAME"
,
"John Smith"
);
-
int
winnings = random() % 100000;
- dict.SetIntValue(
"VALUE"
, winnings);
- TemplateDictionary *dict1 = dict.AddSectionDictionary(
"IN_TABLE"
);
- TemplateDictionary *dict2 = dict.AddSectionDictionary(
"IN_TABLE"
);
- dict1->SetValue(
"ITEM"
,
"Lihaibo"
);
- dict1->SetFormattedValue(
"TAXED_VALUE"
,
"%.2f"
, winnings * 0.83);
- dict2->SetValue(
"ITEM"
,
"Qiyuehua"
);
- dict2->SetFormattedValue(
"TAXED_VALUE"
,
"%.2f"
, winnings * 0.73);
-
if
(1)
- {
- dict.ShowSection(
"IN_TABLE"
);
- }
- TemplateDictionary *dict3 = dict.AddIncludeDictionary(
"INCLUDED_TEMPLATE"
);
- dict3->SetFilename(
"../tpl/ctInclude.tpl"
);
- dict3->SetValue(
"INCLUDE_VAR"
,
"This is a include template."
);
- Template* tpl = Template::GetTemplate(
"../tpl/ctexample.tpl"
,nwsc::DO_NOT_STRIP);
- std::string output;
- tpl->Expand(&output, &dict);
- std::cout << output;
- Template::ClearCache();
-
return
0;
- }
注意:
- 模板字典類似Key和Value的結構,對應的是變數名和值。
- 片斷是可以有多條記錄的,如果要顯示列表,可以定義為片斷,擷取多條記錄填充到字典中。
- 片斷可以顯示,也可以不顯示。如果片斷的字典有資料,顯示。如果片斷的字典沒有資料,預設是不顯示的,可以調用ShowSection來顯示。
2.ctemplate進階
- Modifier(修改器),意思變數的類型(html,js或者其他),會進行校正和編碼處理,比如html類型會將&轉換成
&
。類型有html,pre,url query,javascript,css和json。如果覺得在模板變數中定義這些麻煩,可以在載入模板是使用google::Template::GetTemplateWithAutoEscaping()方法,
使用自動替換模式,指定是Html,js還是css。你可以編寫你自己的modifier,來處理一些特殊的需求。
- Strip(清除器),模板中有一些空行和空白字元,在載入時,可以指定參數,是否需要清除。如
google::STRIP_BLANK_LINES
,google::STRIP_WHITESPACE
。
- ExpandEmitter,在ctemplate中有這個介面,這個介面是在展開模板時,輸出資料用的,預設實現了std::string版本的StringEmitter,這種方式是處理完畢後,才能發送到用戶端,std::string效能並不高。如果你要一個高效率的Web伺服器,則可以用流式的模式。比如自己實現ExpandEmitter介面,實現資料流式發送到客戶瀏覽器。
- 字典copy,如果兩個字典很類似,可以copy一個字典,然後修改,調用
dict->MakeCopy()。
- Template::ClearCache()這句,正式使用時不要加這句,因為模板只要用過一次,就會緩衝起來,ClearCache會加鎖,導致效能下降。