佛山软件定制

新手开发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);
        }

    }
}

 

 

 

 

 

 

 

 

 

 

 

posted on 2013-03-12 14:46  New.min  阅读(136)  评论(0编辑  收藏  举报

导航