kkwebsblog1.0博客系统
kkwebsblog1.0博客系统

kkwebsblog1.0博客系统

水之积也不厚,则其负大舟也无力;风之积也不厚,则其负大翼也无力。
kkwebs个人博客系统
左边缘
[原创]网鸟asp.net模板引擎v2中的变量标记
  更新时间:2009-12-31 0:00:00

   模板引擎这个概念,也不需要再阐述了,其实,如何对模板引擎下个定义,我也不了解。但无论如何,也不管是在asp、php、jsp抑或是asp.net,甚至是javascript当中(嘿嘿,在javascript里面也有类似于模板引擎的东东),模板引擎当中都少不了“变量标记”这么个东东。
有的模板引擎将变量标记称为标签,其实我们也都明白,通过有一定语法约束的标签或者标记,可以很方便的对模板代码“赋值”。实际上模板变量标记是一种替代符,当模板代码经过模板引擎提供程序处理之后,这些标签就变得有意义了,或者生成为我们定义好的一系列的语句,或者是一些文字。除此之外,模板变量标记似乎没有别的什么作用。那么为什么我们非用模板变量标记不可呢?原因至少有以下两个:
一、使用模板变量标记是内容表达的需求。即使在不使用模板引擎的情况下,我们在书写web应用程序的时候(仅仅依靠html、css、javascript、xml编写的静态网站是不能被叫做web应用程序的),都需要输出一些“变量”。对于这些变量,我们无法事先知道他们的值,所以只能让它动态生成,所以在开发语言里面就有了输出这些变量的方法。举一个asp.net下的例子,如果你定义了一个变量:

  1. string websitename = "我的网站";
复制代码
现在需要将它输出到用户代理(或者说浏览器),至少有两种方式:
  1. // 方式一
     
  2. response.write(websitename);
复制代码
或者:
  1. <!-- 方式二 -->
     
  2. <div><% = websitename %></div>
复制代码
其中,第一种方法是在开发语言当中直接输出变量的,第二种方法是嵌入html标记当中的(实质上他们是一样的功能)。也许你想到了,我们在使用模板引擎的时候,所有的要输出的变量都需要嵌入到html标记(或者其他代码中,比如你不打算把模板引擎应用到html当中时,网鸟asp.net模板引擎v2在未来会提供更多应用领域的模板引擎的扩展)当中,那么最合适、最简单的方式就是使用一种唯一格式的字符串来标记它,这样就形成了模板变量标记。使用了唯一格式,在模板引擎提供程序处理模板的时候就可以进行有效的、准确的解析;否则,如果标记格式一团糟,那还怎么工作?
网鸟asp.net模板引擎v2当中约定的模板变量标记有两种形式,一种是动态变量标记(格式为“{$...$}”),一种是静态变量标记(格式为“{#...#}”)。其中,动态变量标记就是用于在代码执行的时候,动态生成我们需要的内容的;而静态变量标记是相对于前者来说的,它是在模板代码被模板引擎提供程序解析的过程当中直接生成为需要的内容的,在生成的代码实际运行过程中,这些“标记”的“内容”是不会改变的,因为它们已经被替换成了最终内容。也许您看了这段文字仍然不了解这是什么意思,我建议您下载网鸟asp.net模板引擎v2的源代码亲自测试一番。
二、使用模板变量标记是实现多层开发的进一步需求。我这里说多层开发而不是简单的mvc,是因为似乎只有多层开发这个概念才能描述出我下面举例的情况。多层开发不一定是mvc,但大多数多层开发模式都可以被看作mvc。
假如,有一个项目要求实现多语言,但这个项目还要要求降低维护成本,使用相同的模板。那么你如何做?是的,我们需要将需要转换为多语言的部分看作为语言包,将这些语言包分离出来独立管理维护,既实现了多语言,也降低了后期的维护成本,并且可以在同一个模板当中任意切换语言类型。
当你将语言包独立出来之后,就发现,我们必须寻找一种方法,让我们的语言包中的条目准确无误的输出到指定的位置,因为我们需要它出现在那里!怎么办?——对了,还是标记!我们约定一种标记格式,用这些标记来表示我们的语言包当中的项,在执行的时候替换它们。这样,我们只需要控制好这些标记的位置,保证它们是准确无误的,就完全可以达到目的了。不是么?
这里还是要提一下网鸟asp.net模板引擎v2当中所设计的静态变量标记了。我们在对模板引擎代码进行后期整理的时候发现,语言包这个东东,实际上在模板生成之后很少去切换它,如果让它们也在运行时当中反复的被运算、解析着,是不是有点浪费资源呢?所以我们又设计了这种叫做静态变量标记的东东,它可以满足这种需求,将某些预先定义的变量,直接替换为最终内容,避免在运行时当中重复运算。
当然,网鸟asp.net模板引擎v2静态变量标记并不仅仅用在语言包上(如果你需要经常切换语言包,请不要使用静态变量标记),还有很多地方需要用它,用心体会吧!
最后,我们来谈谈网鸟asp.net模板引擎v2中模板变量标记的使用。
一、动态变量标记的使用
动态变量标记用起来具有很高的自由度。大家都了解,c#当中所有的类型的基类型都是object,也就是说在c#当中,只要你输入了一段代码它就是类型。那么,在网鸟asp.net模板引擎v2当中,动态变量标记允许你访问任何类型的公开成员,及其子类型(成员所属的类型的成员)的公开成员。只要你拥有访问权限,就可以访问指定类型的任何成员。
使用动态变量标记的一般格式是:{$...$}
在举例之前,我们先假定了一个类型如下:
  1. public sealed class objectinfo
     
  2. {
     
  3. public datetime nowtime = datetime.now;
     
  4. public objectinfo()
     
  5. {
     
  6. this.author = "彦铭工作室";
     
  7. this.generator = "彦铭工作室";
     
  8. this.copyright = "www.htmlbird.net";
     
  9. this.description = "用于代码演示的假定类型";
     
  10. this.keywords = "彦铭,模板引擎,aspx";
     
  11. this.items = new list<string>();
     
  12. this.items.add("item1");
     
  13. this.items.add("item2");
     
  14. this.items.add("item3");
     
  15. this.items.add("item4");
     
  16. }
     

  17.  
  18. public string this[int index]
     
  19. {
     
  20. get
     
  21. {
     
  22. return this.items[index];
     
  23. }
     
  24. }
     

  25.  
  26. public override string tostring()
     
  27. {
     
  28. return string.format("{{ author = {0}, generator = {1}, copyright = {2} }}", this.author, this.generator, this.copyright);
     
  29. }
     

  30.  
  31. public string author { get; set; }
     
  32. public string generator { get; set; }
     
  33. public string copyright { get; set; }
     
  34. public string description { get; set; }
     
  35. public string keywords { get; set; }
     
  36. public list<string> items { get; set; }
     
  37. }
     

  38.  
  39. objectinfo myobjectinfo = new objectinfo();
复制代码
1、使用动态变量标记访问类型的字段
  1. <!-- 直接访问字段 -->
     
  2. <div>{$myobjectinfo.nowtime$}</div>
     
  3. <!-- 访问字段,并调用该字段类型的其他成员 -->
     
  4. <div>{$myobjectinfo.nowtime.adddays(1)$}</div>
     
  5. <div>{$myobjectinfo.nowtime.tostring("r")$}</div>
复制代码
2、使用动态变量标记访问类型的属性
  1. <!-- 直接访问属性 -->
     
  2. <div>{$myobjectinfo.items$}</div>
     
  3. <!-- 访问字段,并调用该属性的类型的其他成员 -->
     
  4. <div>{$myobjectinfo.items[0]$}</div>
     
  5. <div>{$myobjectinfo.items.count$}</div>
     
  6. <div>{$myobjectinfo.items.tostring()$}</div>
复制代码
3、使用动态变量标记访问类型的方法
  1. <!-- 直接访问方法 -->
     
  2. <div>{$myobjectinfo.tostring()$}</div>
     
  3. <!-- 访问字段,并调用该方法的类型的其他成员 -->
     
  4. <div>{$myobjectinfo.tostring().length$}</div>
复制代码
4、使用动态变量标记访问类型的索引器
  1. <!-- 直接访问索引器 -->
     
  2. <div>{$myobjectinfo[0]$}</div>
     
  3. <!-- 访问字段,并调用该索引器的类型的其他成员 -->
     
  4. <div>{$myobjectinfo[0].length$}</div>
     
  5. <div>{$myobjectinfo[0].padleft(20, 0)$}</div>
复制代码
动态变量标记的初始化是在运行时直接声明并处理的,请下载模板引擎的测试代码自行研究
二、静态变量标记的使用
静态变量标记的使用相对来说非常简单,因为在当前情况下,我们也没有将它设计的很复杂,模板引擎提供程序内部存储静态变量的方式是使用一个字符串字典,在{#...#}当中指定的内容就是这个字典的键名,模板引擎提供程序通过这个键名查询到对应的值并输出。
静态变量标记当中无法像动态变量标记那样可以任意调用指定类型的方法、属性、字段、索引器等,以及它们的子类型的成员,因为它只是一个字典!
在这里,我们也非常期盼着c#4.0正式版的发布,获取它提供的动态方法对我们的模板引擎的改进有很大的帮助。再说一次,在当前开发环境下不是实现不了访问未知类型的成员,只是那样做会增加模板引擎自身架构的难度,目前我们没有考虑要这么做。
在使用静态变量标记之前,我们必须将要访问到的静态变量的键和值输入到模板引擎提供程序当中,示例代码如下:
  1. aspxtemplateengine _templateengine = new aspxtemplateengine("mytemplatefile.shtml", "/", applicationinfo.ymind);
     
  2. _templateengine.staticvariables.add("key1", "value1");
     
  3. _templateengine.staticvariables.add("key2", "value2");
     
  4. _templateengine.staticvariables.add("key3", "value3");
     
  5. _templateengine.staticvariables.add("key4", "value4");
     
  6. _templateengine.staticvariables.add("key5", "value5");
     
  7. _templateengine.staticvariables.add("key6", "value6");
复制代码
然后再模板代码当中书写以下代码就可以调用它们了:
  1. <div>{#key1#}</div>
     
  2. <div>{#key2#}</div>
     
  3. <div>{#key3#}</div>
     
  4. <div>{#key4#}, {#key5#}, {#key6#}</div>
需要注意到是,为了提高代码安全性,如果您调用了不存在的键,模板引擎提供程序就会抛出异常,我们认为这样做有利于让大家编写出更高质量的代码。
发表评论
评论人:
邮箱:
QQ:
内容:
验证码:  换一个
右边缘
陕ICP备09000504号