Qter 发表于 2020-2-1 22:26:09

ctemplate

本帖最后由 Qter 于 2020-2-1 22:28 编辑

https://www.xuebuyuan.com/2608449.htmlGoogle开源C++模板库ctemplate完整使用示例
CTemplate是Google开源的一个使用简单但功能很强大的C++模板库,本文简单介绍其的使用。入门示例模板库一般用来隔离数据和展现,这样可以减少数据和展现之间的耦合,使其可以相互独立变化,减少耦合,增加代码的复用,下面我们先看一个简单的例子,模板如下:Hello {{NAME}},
You have just won ${{VALUE}}!
{{#IN_CA}}Well, ${{TAXED_VALUE}}, after taxes.{{/IN_CA}}
对应的C++代码是:

#include <cstdlib>
#include <iostream>
#include <string>
#include <ctemplate/template.h>

int main() {
    ctemplate::TemplateDictionary dict("example");
    int winnings = rand() % 100000;
    dict["NAME"] = "John Smith";
    dict["VALUE"] = winnings;
    dict.SetFormattedValue("TAXED_VALUE", "%.2f", winnings * 0.83);
    // For now, assume everyone lives in CA.
    // (Try running the program with a 0 here instead!)
    if (1) {
      dict.ShowSection("IN_CA");
    }
    std::string output;
    ctemplate::ExpandTemplate("example.tpl", ctemplate::DO_NOT_STRIP, &dict, &output);
    std::cout << output;
    return 0;
}模板中{{NAME}}和{{VALUE}}对应的是变量,在dict中通过dict["NAME"]或dict的setValue的相关方法进行赋值;{{#IN_CA}}和{{/IN_CA}}之间的是一个section,可以通过dict的ShowSection来控制是否要显示这个section。循环有的数据我们需要循环展示,比如一个table的多个tr,ctemplate本身不支持循环,需要C++来控制循环,核心思想是多次Insert Section,示例模板如下:{{#TEST_TABLE}}
<table>
{{#TEST_TABLE_ITEM}}
<tr>
    <td>{{INDEX}}</td>
    <td>{{NAME}}</td>
    <td>{{AGE}}</td>
</tr>
{{/TEST_TABLE_ITEM}}
</table>
{{/TEST_TABLE}}
对于这个模板,我们先显示外面的这个Section,然后再循环多次Insert里面的子Section就可以了,代码如下:

#include <cstdlib>
#include <iostream>
#include <string>
#include <ctemplate/template.h>

int main() {
    ctemplate::TemplateDictionary dict("loop");
    dict.ShowSection("TEST_TABLE");

    for (int i = 0; i != 3; ++i) {
      ctemplate::TemplateDictionary *item = dict.AddSectionDictionary("TEST_TABLE_ITEM");
      item->SetFormattedValue("INDEX", "%d", i);
      item->SetValue("NAME", "阿牛牛牛牛");
      item->SetValue("AGE", "保密");
    }

    std::string output;
    ctemplate::ExpandTemplate("loop.tpl", ctemplate::DO_NOT_STRIP, &dict, &output);
    std::cout << output;
    return 0;
}文件包含 对于一个通常的系统来说,一般都有多个模板文件,这多个模板文件之间,有很多相同的部分,比如有同样的header、footer,为了减少重复的代码,并且以后修改的话,只需修改一个地方,我们可以把公共的部分提取出来,然后其它的模板文件包含这个文件。ctemplate很好的支持了文件包含,对于ctemplate来说,包含的文件也是一个Section,模板代码如下:{{>HEADER}}

{{#TEST_TABLE}}
<table>
{{#TEST_TABLE_ITEM}}
<tr>
    <td>{{INDEX}}</td>
    <td>{{NAME}}</td>
    <td>{{AGE}}</td>
</tr>
{{/TEST_TABLE_ITEM}}
</table>
{{/TEST_TABLE}}
注意第一行的{{>HEADER}},这是一个特殊格式的Section,用来表示文件包含。对应的C++代码如下:

#include <cstdlib>
#include <iostream>
#include <string>
#include <ctemplate/template.h>

int main() {
    ctemplate::TemplateDictionary dict("loop");

    ctemplate::TemplateDictionary *example = dict.AddIncludeDictionary("HEADER");
    example->SetFilename("./header.tpl");
    example->SetValue("TITLE", "测试");
   
    dict.ShowSection("TEST_TABLE");

    for (int i = 0; i != 3; ++i) {
      ctemplate::TemplateDictionary *item = dict.AddSectionDictionary("TEST_TABLE_ITEM");
      item->SetFormattedValue("INDEX", "%d", i);
      item->SetValue("NAME", "阿牛牛牛牛");
      item->SetValue("AGE", "保密");
    }

    std::string output;
    ctemplate::ExpandTemplate("loop.tpl", ctemplate::DO_NOT_STRIP, &dict, &output);
    std::cout << output;
    return 0;
}通过上面的三个示例,掌握了ctemplate的基本使用、循环、文件包含,应该可以满足90%的需求了,如果有其它的需求的话,可以参考ctemplate的官方文档http://code.google.com/p/ctemplate。

页: [1]
查看完整版本: ctemplate