Clearsilver是一套用c语言实现的html模板系统,同时还提供了python、perl、c++等语言的调用接口。Clearsilver本身非常高效,还提供了国际化支持、gzip压缩、字符串转义等功能,在google groups、trac等系统中得到了应用,更多应用请见这里。
Clearsilver的两个基本概念为数据和Clearsilver(CS)模板。模板由html语句和CS语句构成,控制着数据的表现形式。通过使用Clearsilver,可以强制数据和表现分离,有利于后台数据人员和前台数据人员各司其职协同工作,不用修改后台逻辑就可以完成页面的重构。
Clearsilver的数据使用了一种叫做HDF的结构,它支持两种定义方式。第一种是点分路径方式。
Page.Name = My Index Page.URL = /myindex.html Page.Menu.0 = Home Page.Menu.1 = Preferences Page.Menu.2 = Help Page.Menu.3 = Support
第二种是嵌套元素的方式。
Page { Name = My Index URL = /myindex.html Menu { 0 = Home 1 = Preferences 2 = Help 3 = Support } }
Clearsilver的基本使用方式如下:
- 初始化hdf结构
- 填充数据
- 初始化cs模板
- 载入模板文件
- 调用cs_render完成页面的渲染
最后是一个简单的示例
test.html 模板文件
1: <?cs if:subcount(article.list) != #0?>
2: <table>
3: <tr><th>序号</th><th>作者</th><th>日期</th><th>标题</th></tr>
4: <?cs each:item=article.list ?>
5: <tr>
6: <td><?cs var:item.id ?></td>
7: <td><a href="/author_info.cgi?author=<?cs var:item.author ?>"><?cs var:item.author ?></a></td>
8: <td><?cs var:item.publish_time ?></td>
9: <td><a href="/show_article.cg?id=<?cs var:item.id ?>"><?cs var:item.title ?></a></td>
10: </tr>
11: <?cs /each ?>
12: </table>
13: <?cs /if ?>
test.c 程序文件
1: #include "ClearSilver.h"
2: #include <time.h>
3: #include <stdio.h>
4:
5: #define ID_LEN 16
6: #define TITLE_LEN 64
7: struct article
8: {
9: int id;
10: char author[ID_LEN];
11: time_t publish_time;
12: char title[TITLE_LEN];
13: };
14: /* hdf结构
15: * article{
16: list{
17: 0 {
18: id =
19: author =
20: publish_time =
21: title =
22: }
23: 1 {
24: id =
25: author =
26: publish_time =
27: title =
28: }
29: ...
30: }
31: }
32: */
33:
34: NEOERR * print_cs(void *ctx, char *result)
35: {
36: printf("%s", result);
37: return STATUS_OK;
38: }
39:
40: int main()
41: {
42: const int ARTICLE_NUM = 5;
43: struct article articles[ARTICLE_NUM];
44: int i;
45: for( i = 0 ; i < ARTICLE_NUM ; i++ )
46: {
47: articles[i].id = i+1;
48: snprintf(articles[i].author, sizeof(articles[i].author), "author%d", i);
49: articles[i].publish_time = time(NULL) - 100 * i;
50: snprintf(articles[i].title, sizeof(articles[i].title), "标题--%d", i);
51: }
52:
53: nerr_init();
54: NEOERR *err;
55: HDF *hdf;
56: err = hdf_init(&hdf);
57: if( err != STATUS_OK )
58: {
59: /* nerr_log_error logs the error to stderr and cleans up */
60: nerr_log_error(err);
61: return -1;
62: }
63:
64: char buf[1024];
65: char key[64];
66: for(i = 0; i < ARTICLE_NUM; i++)
67: {
68: snprintf(key, sizeof(key), "article.list.%d.id", articles[i].id);
69: hdf_set_int_value(hdf, key, articles[i].id);
70:
71: snprintf(key, sizeof(key), "article.list.%d.author", articles[i].id);
72: hdf_set_value(hdf, key, articles[i].author);
73:
74: snprintf(key, sizeof(key), "article.list.%d.publish_time", articles[i].id);
75: hdf_set_value(hdf, key, ctime(&articles[i].publish_time));
76:
77: snprintf(key, sizeof(key), "article.list.%d.title", articles[i].id);
78: hdf_set_value(hdf, key, articles[i].title);
79: }
80:
81: /*
82: * 把hdf结构dump到文件中
83: hdf_write_file(hdf, "123.html");
84: */
85:
86: CSPARSE *parse;
87: err = cs_init(&parse, hdf);
88: if( err != STATUS_OK )
89: {
90: nerr_log_error(err);
91: return -1;
92: }
93: err = cs_parse_file(parse, "test.html");
94: if( err != STATUS_OK )
95: {
96: nerr_log_error(err);
97: return -1;
98: }
99: err = cs_render(parse, NULL, print_cs);
100: if( err != STATUS_OK )
101: {
102: nerr_log_error(err);
103: return -1;
104: }
105: cs_destroy(&parse);
106: hdf_destroy(&hdf);
107: return 0;
108: }
makefile
1: all:test.c
2: gcc -g test.c -I /home/neoli/usr/include/ClearSilver/ -L/home/neoli/usr/lib -lneo_cs -lneo_utl