新手开发asp.net模板引擎(1): 一个简单的模板
使用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); } } }
原创内容请您保留出处及地址 , 主页:展益