Use VTemplate template engine - Advanced articles

. 1, < : VT Template <> and : include vt different> tag

< VT: Template > and < VT: the include > tag contains the file attributes, if these two labels are set file attributes, that these two labels look very similar, and the final result is the contents of the file included. But for the template engine is the difference between them is very large.

< VT: Template > tag is "die plate" label, it has its own "variable", it will become a "host template" tag inside it ( OwnerTemplate ). The < VT: the include > the contents of the file will simply include it, "host template" tag inside it and it is the same.

Now if there is a template file VT:  inc_content.html

I was in the file that contains the variable $ {: # .var1 }. 
I include files in the foreach tag: 
< VT: foreach  from = "$ # .names " Item = " #. Name " index = " #. I "> 
include file first $ {: # .i } a name $ {: # .name }. 
</ VT: the foreach >

Now respectively < VT: Template > and < VT: the include > tag file to include the above, as follows: 

A, < VT: Template > comprising:

I was outside of the variable $ {: # .var1 }. 
I was outside the foreach tag: 
< VT: foreach  from = "$ # .names " Item =. "# Name " index =. "# I "> 
outside of {$: # .i } a {$ name: .name # }. 
</ VT: the foreach
< VT: Template  ID = "inc is" File = "inc_content.html" />


B, < VT: the include > comprising:

I was outside of the variable $ {: # .var1 }. 
I was outside the foreach tag: 
< VT: foreach  from = "$ # .names " Item =. "# Name " index =. "# I "> 
outside of {$: # .i } a {$ name: .name # }. 
</ VT: the foreach
< VT: the include  ID = "inc is" File = "inc_content.html" />


The above two VT template code look very similar, but A is parsed after var1 and this inc < VT: Template > variables under formwork panels var1 exist individually, independently of each other! And B variables var1 and this inc < VT: the include > variables var1 equal, all references to the same variable (similar to the other variables).

Now, if A, B are two's VT template code by processing through the following procedures:

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


That is the only external variables var1 , names assigned by the template engine parses the final output, their output results are as follows: 
vtemplate_3_snap_1

Seen from FIG., < VT: Template > contains no data output, and with < VT: the include > contains the data and external data and outputs identical! So can the < VT: Template > tag as a programming language in the class , it has its own variables, change the value of external variables will not affect its internal variables of the same name, and the outer label can be obtained by its id internal variables !

Specific examples of codes, refer to: http://net-vtemplate.googlecode.com/svn/src/VTemplate.WebTester/template_include_test.ashx.cs

 

 

2, the use of variable expression

Available in variable expression tag attributes can also be used in the variable element. Its role is a field variables, properties, methods, or the result value of the function for obtaining an index. In the example embodiment # .var1 is described to obtain the value of the variables var1, that is, the value "1."

For the type of variable value in the field of real, property or function method, VT template engine acquired by reflecting the value of the result , for example, VT template code:

My name is $ {: the User . Name }, year, $ {: the User . Age } years old, I'm from $ {: the User . LOCATION . GetCity () }


If the assigned value for the user class instance variables, when the above template code template engine will be able to parse correctly parse out the final value of each variable expression.

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>标签)的属性里,这样我们就能在程序代码里获取到这些外部条件并加以处理数据

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

vtemplate_3_snap_2

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

<div class="side_block"> 
  <h3 class="title_blue">相关新闻</h3> 
  <vt:template name="topnewstype="relating" file="cnblogs_newsdata.html" /> 
</div> 
<div class="side_block"> 
  <h3 class="title_yellow">热点新闻</h3> 
  <vt:template name="topnewstype="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

 

Note: The template engine technology have been established VTemplate exchange QQ group, to welcome you all to participate in project development or technology to explore added. QQ group: 884 468

Guess you like

Origin www.cnblogs.com/Jeely/p/11346344.html