1、<vt:template>与<vt:include>标签的不同

<vt:template>和<vt:include> 标签都包含file属性,如果这两个标签都设置file属性,那这两个标签看起来很相似,并且最终效果都是将文件的内容包含进来。但是对于模板引擎来说它们之间的差别却是非常的大。

<vt:template>标签是“模板块”标签,它能拥有自己的“变量”,它会成为它内部的标签的“宿主模板”(OwnerTemplate)。而<vt:include>则只是简单的将文件内容包含进来,它内部的标签的“宿主模板”与它相同。

现假如有一个VT模板文件: inc_content.html

我是包含文件里的变量 {$:#.var1}。 
我是包含文件里的foreach标签: 
<vt:foreach from=”$#.names” item=”#.name” index=”#.i”> 
包含文件的第{$:#.i}个名字叫{$:#.name}。 
</vt:foreach>

现分别用<vt:template> 和 <vt:include>标签去包含上面的文件,如下:

A、<vt:template>包含:

我是外部的变量{$:#.var1}。 
我是外部的foreach标签: 
<vt:foreach from=”$#.names” item=”#.name” index=”#.i”> 
外部的第{$:#.i}个名字叫{$:#.name}。 
</vt:foreach> 
<vt:template id=”inc” file=”inc_content.html” />

B、<vt:include>包含:

我是外部的变量{$:#.var1}。 
我是外部的foreach标签: 
<vt:foreach from=”$#.names” item=”#.name” index=”#.i”> 
外部的第{$:#.i}个名字叫{$:#.name}。 
</vt:foreach> 
<vt:include id=”inc” file=”inc_content.html” />

上面两块的VT模板代码看起来很相似,但是经解析后A中的var1与inc这个<vt:template>模板块下的变量var1分别独立存在,互不影响!而B中的变量var1与inc这个<vt:include>的变量var1相等,都是引用同一个变量(其它变量类似)。

现假如A、B两块的VT模板代码都通过过下面的程序来处理:

this.Document.Variables.SetValue("var1", 1); 
this.Document.Variables.SetValue("names", new string[] { "张三", "李四", "王五" });

也即是只对外部变量var1、names赋值,最终经模板引擎解析输出后,它们的输出结果如下: 

从图可知,<vt:template>包含的没有数据输出,而用<vt:include>包含则有数据输出并且和外部数据一模一样!所以可把<vt:template>标签看成是程序语言里的类,它能拥有它自己的变量,改变外部变量的值不会影响到其内部的同名变量,并且外部标签可通过其id获取其内部变量!

具体的示例代码,请参考:http://net-vtemplate.googlecode.com/svn/src/VTemplate.WebTester/template_include_test.ashx.cs

2、使用变量表达式

变量表达式可用在标签属性,也可用在变量元素中。它的作用就是用于获取变量中某个字段、属性、函数方法或索引的结果值。比如上例中的#.var1就是说明获取var1变量的值,也即是数值“1”。

对于变量值类型中真实存在的字段、属性或函数方法,VT模板引擎将通过反射获取其结果值,例如以下VT模板代码:

我叫{$:user.name},今年{$:user.age}岁,我来自{$:user.location.getcity()}

假如对user变量赋以下类实例的值,那么上面模板代码解析时模板引擎将能正确解析出各个变量表达式的最终值。

class Location 
{    
    public string GetCity(){ 
         //code here 
    } 
}

class User 

    public string Name { get; set; } 
    public int Age { get; set; } 
    public Location Location { get; set; } 
}

但在某些情况下,我们需要获取的“值”并不简单地存在变量值的类型中,而是需要经过其它处理运算得出来的值。比如上面的获取个人资料里,我们还要获取用户的个人财产总额,但从上面的代码里可看出个人财产总额项并不存在于User类里,所以导致VT模板引擎根本无法获取此项的值。那我们要如何做才能获取此项数据呢?VT模板引擎提供了一个手动设置变量表达式的值的方法,而我们要做的就是根据此方法手动设置变量表达式的值!例如上面的VT模板代码改为如下:

我叫{$:user.name},今年{$:user.age}岁,我来自{$:user.location.getcity()},我的个人财产总共有{$:user.totalmoney}元。

从上面的类实例代码中可知道totalmoney这个项是不存在User的属性/字段列表里的,所以我们就要手动设置{$:user.totalmoney}的值,示例代码如下:

/// <summary> 
/// 返回某个用户的个人财产总额 
/// </summary> 
/// <param name="user"></param> 
/// <returns></returns> 
static int GetUserTotalMoney(User user) 

    //code here 
}

//------------------------使用代码----------------------------------------//

//获取user变量 
Variable userVar = this.Document.Variables["user"]; 
//生成User实例 
User user = new User(); 
//…………其它代码略去…………// 
//设置user变量的值为User实例 
userVar.Value = user; 
//手动设置totalmoney的值(注意,这行和上面那行的顺序不能搞乱) 
userVar.SetExpValue("totalmoney", GetUserTotalMoney(user));

3、有条件的控制数据的输出

在输出数据时,我们并不是简单的输出所有数据,而是要根据外部的许多条件组合获取其中的部分数据。而对于这些外部条件,如果可固定的则我们可以在设计VT模板时将其写入到标签(建议是<vt:template>标签)的属性里,这样我们就能在程序代码里获取到这些外部条件并加以处理数据。

例如博客园的新闻频道里右边的“相关新闻”、“热点新闻”两栏数据,如下图:

假设“相关新闻”里获取的新闻是属于"relating”类型的新闻,而“热点新闻”则是获取属于"hoting”类型的新闻,则我们可以设计其VT模板如下:

<div class="side_block"> 
  <h3 class="title_blue">相关新闻</h3> 
  <vt:template name="topnews" type="relating" file="cnblogs_newsdata.html" /> 
</div> 
<div class="side_block"> 
  <h3 class="title_yellow">热点新闻</h3> 
  <vt:template name="topnews" type="hoting" file="cnblogs_newsdata.html" /> 
</div>

在上面的VT模板中,定义了两个name为"topnews”的<vt:template>标签,这是为了便于在代码里对这两个<vt:template>进行统一处理(因为它们要处理的数据都是相同,只是获取数据条件不同)而定义的名称。并且分别定义了自定义属性type用于做数据获取条件。其中包含文件cnblogs_newsdata.html的VT模板如下:

<ul class="topnews block_list bt"> 
  <vt:foreach from="$#.newsdata" item="#.news" index="#.i" id="newslist"> 
  <li> 
    <a href="{$:#.news.url}" title="{$:#.news.title htmlencode='true'}">{$:#.news.title htmlencode='true'}...</a> 
  </li> 
  </vt:foreach> 
</ul>

在此文件的VT模板中,定义了一个id为"newslist"的<vt:foreach>标签,定义此id是为了在程序代码里控制新闻的输出和处理每条新闻的访问地址,也即是"{$:#.news.url}”变量表达式的值。

示例代码:

//获取所有名称为topnews的模板块 
ElementCollection<Template> templates = this.Document.GetChildTemplatesByName("topnews"); 
foreach (Template template in templates) 

    //根据模板块里定义的type属性条件取得新闻数据 
    List<News> newsData = GetNewsData(template.Attributes.GetValue("type")); 
    //设置变量newsdata的值 
    template.Variables.SetValue("newsdata", newsData);

//取得模板块下Id为newslist的标签(也即是在cnblogs_newsdata.html文件中定义的foreach标签) 
    Tag tag = template.GetChildTagById("newslist"); 
    if (tag is ForEachTag) 
    { 
        //如果标签为foreach标签则设置其BeforeRender事件用于设置变量表达式{$:#.news.url}的值 
        tag.BeforeRender += (sender, e) => 
        { 
            ForEachTag t = (ForEachTag)sender; 
            //取得当前项的值(因为foreach标签的数据源是List<News>集合,所以当前项的值类型为News实体) 
            News news = (News)t.Item.Value; 
            //设置当前项的变量表达式的值.也即是"{$:#.news.url}"变量表达式 
            t.Item.SetExpValue("url", GetNewsUrl(news)); 
        }; 
    } 
}

在上面代码中使用了BeforeRender事件,此事件是在标签元素的数据呈现之前触发。对于循环元素<vt:foreach>和<vt:for>,因为每次循环时都会呈现数据,也就导致每次循环时都会触发此事件(包括AfterRender事件),所以我们就可通过此事件方法获取到循环当前项的值。

具体的示例代码,请参考:http://net-vtemplate.googlecode.com/svn/src/VTemplate.WebTester/cnblogs_newslist.ashx.cs

VTemplate项目托管在Google code上。 
URL: http://net-vtemplate.googlecode.com/ 
SVN: http://net-vtemplate.googlecode.com/svn/src/VTemplate.Engine/

更多例子请参考VTemplate.WebTester项目

http://net-vtemplate.googlecode.com/svn/src/VTemplate.WebTester/

或观看在线演示例子:(感谢网友“DOLT”、疯子” 提供

http://61.155.39.222:8888/index.ashx

注:已建立VTemplate模板引擎技术交流QQ群,欢迎各位加入参与项目开发或技术探讨。QQ群:884468

VTemplate模板引擎的使用--进阶篇的更多相关文章

  1. VTemplate模板引擎的使用--高级篇

    VTemplate模板引擎的使用--高级篇 在网站中,经常会有某个栏目的数据在多个页面同时使用到.比如新闻网站或电子商务网站的栏目列表,几乎在很多页面都会显示栏目导航.对于这种多个页面同时使用到的“数 ...

  2. VTemplate模板引擎的使用--入门篇

    1.什么是VTemplate模板引擎? 详细请点击这里. 2.怎样使用VTemplate模板引擎? 第1步: 下载VTemplate模板引擎的最新库文件(从这里下载),下载回来后将库文件引入到你的项目 ...

  3. 使用VTemplate模板引擎动态生成订单流程图

    1.VTemplate模板引擎的简介 VTemplate模板引擎也简称为VT,是基于.NET的模板引擎,它允许任何人使用简单的类似HTML语法的模板语言来引用.NET里定义的对象.当VTemplate ...

  4. 基于.NET的免费开源的模板引擎---VTemplate(转)

    1.VTemplate模板引擎的简介 VTemplate模板引擎也简称为VT,是基于.NET的模板引擎,它允许任何人使用简单的类似HTML语法的模板语言来引用.NET里定义的对象.当VTemplate ...

  5. JS模板引擎 :ArtTemplate (2)

    上一篇初略的介绍了一下javascript中的模板引擎,有兴趣的可以戳 这里 . 这一篇将带着大家一起做一个简易的模板引擎, 上一篇介绍到:模板引擎其实做的就是两件事. 根据一定的规则,解析我们所定义 ...

  6. JavaEE开发之SpringBoot整合MyBatis以及Thymeleaf模板引擎

    上篇博客我们聊了<JavaEE开发之SpringBoot工程的创建.运行与配置>,从上篇博客的内容我们不难看出SpringBoot的便捷.本篇博客我们继续在上篇博客的基础上来看一下Spri ...

  7. .NET Core/.NET5/.NET6 开源项目汇总13:模板引擎

    系列目录     [已更新最新开发文章,点击查看详细] 开源项目是众多组织与个人分享的组件或项目,作者付出的心血我们是无法体会的,所以首先大家要心存感激.尊重.请严格遵守每个项目的开源协议后再使用.尊 ...

  8. .net 开源模板引擎jntemplate 实战演习:基础篇之入门

    一.简介 模板引擎是Web开发中非常重要的一环,它负责将页面上的动态内容呈现出最终的结果展现给前端用户,在asp.net mvc中,我们最熟悉的就是Razor了,作为官方的视图引擎(视图引擎不等同于模 ...

  9. .net 开源模板引擎jntemplate 教程:基础篇之在ASP.NET MVC中使用Jntemplate

    在ASP.NET MVC 中使用Jntemplate 上一篇我们详细介绍了jntemplate的标签语法,本篇文章将继续介绍如何在ASP.NET MVC 中使用Jntemplate. 一.使用Jnte ...

随机推荐

  1. charles抓包看性能数据

    1.优化某个接口或加载速度(H5加载速度慢) 抓包看Overview ①看Duration,就是接口的加载时间 ②看Latency,就是延时一端传播到另一端所花费的时间:一般和网络有关:可以综合Dur ...

  2. 面试题57:数组中2个数的和(也是leetcode题目)

    题目:给定一个整数数列,找出其中和为特定值的那两个数. 你可以假设每个输入都只会有一种答案,同样的元素不能被重用. 示例: 给定 nums = [2, 7, 11, 15], target = 9 因 ...

  3. pandas相关操作

    import pandas as pd import numpy as np ''' 一.创建df 1.定义df :传递字典 1.1每一列的名称作为键 每个键都有一个数组作为值[key:数组] 1.2 ...

  4. python类与对象

    1.  class命名规范:首字母大写,驼峰命名法 2.  class 里面函数括号里面带(self)说明这是一个实例,调用实例方法需要用实例调用 class Teacher: def  test_1 ...

  5. php mysql 多表查询之子查询语句

    所谓子查询语句,就是先通过一个语句来查询出一个结果,然后再通过一个查询语句从这个结果中再次查询.子查询语句一般有以下3种.下面以一个案例来做讲解. 案例:查询[例1]中每个分类下的最新的那一条商品信息 ...

  6. golang的数据类型之字符类型

    字符类型使用细节 1)字符常量是用单引号('')括起来的单个字符.例如:var c1 byte = 'a' var c2 int = '中' var c3 byte = '9' 2) Go中允许使用转 ...

  7. 图推荐-基于随机游走的personrank算法

    转自http://blog.csdn.net/sinat_33741547/article/details/53002524 一 基本概念 基于图的模型是推荐系统中相当重要的一种方法,以下内容的基本思 ...

  8. redis集群搭建(简单简单)一台机器多redis

      redis集群搭建 在开始redis集群搭建之前,我们先简单回顾一下redis单机版的搭建过程 下载redis压缩包,然后解压压缩文件: 进入到解压缩后的redis文件目录(此时可以看到Makef ...

  9. python面试题之简要描述Python的垃圾回收机制(garbage collection)

    这里能说的很多.你应该提到下面几个主要的点: Python在内存中存储了每个对象的引用计数(reference count).如果计数值变成0,那么相应的对象就会小时,分配给该对象的内存就会释放出来用 ...

  10. RabbitMq--2--安装

    简单说下个人的理解,mq就是一个消息代理,负责异步消息转发,可以很大程度缓解服务器压力,并且防止服务器宕机影响业务等. 安装: 环境:centos7 1).首先需要安装erlang #wget htt ...