使用asp.net創建自己的模板引擎是相當簡單的事情,而我們所使用的僅僅需要正則和反射兩個工具就足夠了。 來看看下麵一個來自於真實項目的模板頁(者進行了適當的精簡,為方便閱讀): ? <!DOCTYPE html> <html> <head> <title>${SYS_NAME}</title> < ...
使用asp.net創建自己的模板引擎是相當簡單的事情,而我們所使用的僅僅需要正則和反射兩個工具就足夠了。
來看看下麵一個來自於真實項目的模板頁(者進行了適當的精簡,為方便閱讀):
?
<! DOCTYPE html>
< html >
< head >
< title >${SYS_NAME}</ title >
</ head >
< body >
$require('${id}')
${partial:"common/blog.header.phtml"}
< div class="sitepath">您當前的位置:< a href="${SYS_DOMAIN}" rel="nofollow">首頁</ a >>$sitemap('${categoryTag}')>${title}</ div >
<!-- 顯示文檔 -->
$archive('${id}','
< h1 >{title}</ h1 >
< p class="meta">作者:{authorname} 發佈時間:{createtime2} 瀏覽次數:
< span class="hightlight">{count}</ span > 評論:< span class="hightlight">{replay}</ span > 條< br />
{content}
</ p >
')
< div class="relation" style="text-align:center;padding:20px 0">
上一篇:$prevarchive('${id}','< a href="{url}">{title}</ a >') | 下一篇:$nextarchive('${id}','< a href="{url}">{title}</ a >')
< br />關鍵詞:
$tags('${tags}','< a href="{searchurl}" target="_blank">{name}</ a > ')
</ div >
<!-- 文檔評論 -->
< div class="comments" id="comments">
< ul >
$comment('< li id="comment{id}">< span class="meta">< span class="floor">{index}樓</ span >
< span class="user">{nickname}</ span > 於 < span class="date">{date}說:</ span >< span class="content">{content}</ span ></ li >'
,'false','true')
</ ul >
</ div >
< div id="submitComment">
< span class="title">發佈評論</ span >
$comment_editor('','true')
</ div >
${partial:"common/blog.footer.phtml"}
</ body >
</ html >
|
在這個模板頁中,使用$method(param) 來調用數據所提供的方法,在方法內部可以接受一個模板片段參數,改參數使用{paramName} 傳入,並返回數據。
通過文件,我們不難看出這是一個博客的博文顯示頁面,包括了評論功能。通過插槽式的組合,我們可以通過修改這個文件而無需重寫代碼(僅對功能相對固定的系統),充分使用模板帶來的便利優勢。接下來的一系列文章,將通過對這個模板引擎的分析,教新手開發一個自定義的模板引擎。...
以下是片段代碼:SmpleTpl.cs
?
/*******************************************
* 文 件 名:SimpleTpl.cs
* 文件說明:asp.net模板引擎解析文件
* 創 建 人:newmin
* 個人博客: http://blog.ops.cc
******************************************/
namespace U1City.Shop.Unit
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;
/// <summary>
/// 簡單模板解析類
/// </summary>
public sealed class SimpleTpl
{
/// <summary>
/// 包含方法的類型實例
/// </summary>
private object classInstance;
public SimpleTpl( object classInstance)
{
this .classInstance = classInstance;
}
/// <summary>
/// 數據列正則
/// </summary>
private static Regex fieldRegex = new Regex( "{([a-z0-9_]+)}" );
/// <summary>
/// 執行解析模板內容
/// </summary>
/// <param name="html"></param>
/// <returns></returns>
public static string Execute( object instance, string html)
{
string resultTxt = html; //返回結果
const string tagPattern = "\\$([a-z0-9]+)\\(([^)]+')\\)" ;
const string paramPattern = "'([^']+)',*" ;
Regex tagRegex = new Regex(tagPattern); //方法正則
Regex paramRegex = new Regex(paramPattern); //參數正則
Type type = instance.GetType();
MethodInfo method;
string tagName;
object [] parameters;
Type[] parameterTypes; //參數類型數組
MatchCollection paramMcs;
resultTxt = tagRegex.Replace(resultTxt, m =>
{
tagName = m.Groups[1].Value;
string x = m.Groups[2].Value;
//獲得參數
paramMcs = paramRegex.Matches(m.Groups[2].Value);
parameters = new object [paramMcs.Count];
//查找是否存在方法(方法參數均為string類型)
parameterTypes = new Type[parameters.Length];
for ( int i = 0; i < parameterTypes.Length; i++)
{
parameterTypes[i] = typeof (String);
}
method = type.GetMethod(
tagName,
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase,
null ,
parameterTypes,
null );
//如果方法存在則執行返回結果,否則返回原始值
if (method == null )
{
return m.Value;
}
else
{
//則給參數數組賦值
for ( int i = 0; i < paramMcs.Count; i++)
{
parameters[i] = paramMcs[i].Groups[1].Value;
}
//執行方法並返回結果
return method.Invoke(instance, parameters).ToString();
}
});
return resultTxt;
}
/// <summary>
/// 執行解析模板內容
/// </summary>
public string Execute( string html)
{
return Execute( this .classInstance, html);
}
}
}
|