2012年8月26日星期日

Clearsilver简介

Clearsilver简介

Clearsilver是一套用c语言实现的html模板系统,同时还提供了python、perl、c++等语言的调用接口。Clearsilver本身非常高效,还提供了国际化支持、gzip压缩、字符串转义等功能,在google groups、trac等系统中得到了应用,更多应用请见这里。

Clearsilver的两个基本概念为数据和Clearsilver(CS)模板。模板由html语句和CS语句构成,控制着数据的表现形式。通过使用Clearsilver,可以强制数据和表现分离,有利于后台数据人员和前台数据人员各司其职协同工作,不用修改后台逻辑就可以完成页面的重构。

Clearsilver-Architecture

Clearsilver的数据使用了一种叫做HDF的结构,它支持两种定义方式。第一种是点分路径方式。

Page.Name = My IndexPage.URL = /myindex.htmlPage.Menu.0 = HomePage.Menu.1 = PreferencesPage.Menu.2 = HelpPage.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=&lt;?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=&lt;?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

TAG: