佛山软件定制

新手开发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   New.min  阅读(1293)  评论(1编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述

导航

点击右上角即可分享
微信分享提示