开发网站需要用到模板引擎,自己写了一个。支持foreach嵌套,支持if else嵌套,支持foreach和if else混合嵌套,支持include,支持set,支持cutstr和html2text函数。
html模板示例代码如下:
index.html页面:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta content="width=device-width, minimum-scale=1,initial-scale=1, maximum-scale=1, user-scalable=1;" id="viewport" name="viewport" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="keywords" content="${site.keywords}" /> <meta name="description" content="${site.description}" /> <link href="theme/css/Int.css" rel="stylesheet" /> <link href="theme/css/head.css" rel="stylesheet" /> <link href="theme/css/index.css" rel="stylesheet" /> <link href="theme/css/lrtk.css" rel="stylesheet" /> <link href="theme/css/more.css" rel="stylesheet" /> <script type="text/javascript" src="theme/js/jquery-1.11.3.js"></script> <script type="text/javascript" src="theme/js/layout.js"></script> <script type="text/javascript" src="theme/js/more.js"></script> <script src="theme/js/jquery.superslide.2.1.1.js" type="text/javascript"></script> <title>首页-${site.siteName}</title> <script type="text/javascript"> </script> </head> <body> <!--头部开始--> <div class="header"> <div class="w"> <div class="fl logo"> <a href="/"> <img src="${site.logoUrl}"> </a> </div> <div class="sj_language"> <#if ${site.id}=="1"> <a href="/en/index.html"><em class="china" style="background: url(theme/images/eng.jpg) left center no-repeat;">English</em><i style="background: url(theme/images/china.jpg) left center no-repeat;">中文版</i></a> <#else> <a href="/cn/index.html"><em class="china">中文版</em><i>English</i></a> <#end if> </div> <!--主菜单--> <#include src="/templates/${site.folder}/rootmenu.html" /> <div class="language"> <#if ${site.id}=="1"> <a href="/en/index.html"><span class="china" style="background: url(theme/images/eng.jpg) left center no-repeat;">English</span><i style="background: url(theme/images/china.jpg) left center no-repeat;">中文版</i></a> <#else> <a href="/cn/index.html"><span class="china">中文版</span><i>English</i></a> <#end if> </div> <div class="clear"></div> </div> <div class="clear"></div> <!--子菜单--> <#include src="/templates/${site.folder}/submenu.html" /> <!--头部结束--> <div class="SimpoAll"> <!-- 新的轮播图开始 --> <script type="text/javascript"> var scrollImg; </script> <div class="mrbox"> <span class="next" onclick="scrollImg.next()"></span> <div class="imgbox"> <ul> <#foreach list="banners" model="ban" where="siteId=1" > <li><a href="${ban.linkUrl}" target="_blank"> <img src="${ban.imgUrl}" /></a></li> <#/foreach> </ul> </div> <span class="prve" onclick="scrollImg.prev()"></span> </div> <script src="theme/js/slider-H5.js"></script> <script type="text/javascript"> (function () { $(window).resize(function () { var ul = $('.imgbox').clone().html(); $('.imgbox').html(""); var id = (new Date()).getTime(); $(ul).attr('id', id).appendTo($('.imgbox')); var height = $('body').height(); var width = $('body').width(); var newwidth = $('.imgbox').width(); $('.imgbox').css('width', width); $('.imgbox ul li').css('width', width); $('.imgbox ul li img').css('width', width); /* 注意:$.mggScrollImg返回的scrollImg对象上有 next,prev,go三个方法,可以实现外部对滚动索引的控制。 如:scrollImg.next();//会切换到下一张图片 scrollImg.go(0);//会切换到第一张图片 */ scrollImg = $.mggScrollImg('#' + id, { loop: true,//循环切换 auto: true,//自动切换 auto_wait_time: 3000,//轮播间隔 scroll_time: 300,//滚动时长 callback: function (ind) {//这里传过来的是索引值 $('#page').text(ind + 1); } }); }); $(window).resize(); })() </script> <!-- 新的轮播图结束 --> <div class="clear"></div> <!--关于我们开始--> <div class="about_bg"> <div class="about"> <#set data="channel" model="gywm" where="title='关于我们'" /> <#set data="channel" model="qyjj" where="title='企业简介'" /> <h1 class="biaot"><a href="/${site.folder}/list${qyjj.id}.html">${gywm.title}</a></h1> <#foreach list="channel" model="subMenu" where="parent.Title='关于我们'" > <dl> <dt><a href="/${site.folder}/list${subMenu.id}.html"> <img src="${subMenu.iconUrl}" /></a></dt> <dd><a href="/${site.folder}/list${subMenu.id}.html">${subMenu.title}</a></dd> </dl> <#/foreach> </div> </div> <!--关于我们结束--> <!--业务单元开始--> <#set data="channel" model="ywdy" where="title='业务单元'" /> <div class="Business_bg"> <a href="#"> <div class="Business"> <h1 class="biaot">${ywdy.title}</h1> <div class="yw_pic"> <img src="theme/images/yw.png" /> </div> </div> </a> </div> <!--业务单元结束--> <!--投资者关系开始--> <div class="investor_bg"> <div class="investor"> <#set data="channel" model="tzzgx" where="title='投资者关系'" /> <#set data="channel" model="cwbg" where="title='财务报告'" /> <h1 class="biaot"><a href="/${site.folder}/list${cwbg.id}.html">投资者关系</a></h1> <#foreach list="content" model="con" where="channel.title='投资者关系'" page="1" pageSize="1" > <p>${cutstr(${con.contents},315)}...<a href="/${site.folder}/content${con.id}.html">【详情】</a></p> <#/foreach> <#foreach list="channel" model="subMenu" where="parent.Title='投资者关系'" > <dl> <dt><a href="/${site.folder}/list${subMenu.id}.html"> <img src="${subMenu.iconUrl}" /></a></dt> <dd><a href="/${site.folder}/list${subMenu.id}.html">${subMenu.title}</a></dd> </dl> <#/foreach> </div> </div> <!--投资者关系结束--> <!--新闻综合类开始--> <div class="information"> <!--新闻资讯开始--> <div class="news"> <#set data="channel" model="xwzx" where="title='新闻中心'" /> <#set data="channel" model="mtjj" where="title='媒体聚焦'" /> <h1><a href="/${site.folder}/list${mtjj.id}.html">${xwzx.title}</a></h1> <span><a class="current news1"></a><a class="news2"></a></span> <div class="newbox1"> <#foreach list="content" model="con" where="channel.title='媒体聚焦'" page="1" pageSize="3" > <dl> <dt><a href="/${site.folder}/content${con.id}.html"> <img src="${con.imgUrl}" /></a></dt> <dd> <h2><a href="/${site.folder}/content${con.id}.html">${con.title}</a></h2> <label>${con.publishTime}</label> <p>${cutstr(${con.contents},90)}...<a href="/${site.folder}/content${con.id}.html">【详情】</a></p> </dd> </dl> <#/foreach> </div> <div class="newbox2" style="display: none"> <#foreach list="content" model="con" where="channel.title='最新公告'" page="1" pageSize="3" > <dl> <dt><a href="/${site.folder}/content${con.id}.html"> <img src="${con.imgUrl}" /></a></dt> <dd> <h2><a href="/${site.folder}/content${con.id}.html">${con.title}</a></h2> <label>${con.publishTime}</label> <p>${cutstr(${con.contents},90)}...<a href="/${site.folder}/content${con.id}.html">【详情】</a></p> </dd> </dl> <#/foreach> </div> </div> <!--新闻资讯结束--> <!--社会责任开始--> <div class="responsibility"> <#set data="channel" model="shzr" where="title='社会责任'" /> <h1><a href="/${site.folder}/list${shzr.id}.html">${shzr.title}</a></h1> <div class="zeren"> <div class="border"></div> <div class="zr_list"> <ul> <#foreach list="content" model="con" where="channel.title='社会责任'" page="1" pageSize="5" > <li><#if ${con.curPageSort}==1> <button class="btn_on btn" type="button"></button> <#else> <button class="btn" type="button"></button> <#end if> <a href="/${site.folder}/content${con.id}.html">${con.title}</a> <div class="neir"> <p>${cutstr(${con.contents},60)}...<a href="/${site.folder}/content${con.id}.html">【详情】</a></p> </div> </li> <#/foreach> </ul> </div> </div> </div> <!--社会责任结束--> </div> <!--新闻综合类结束--> <!--总裁寄语开始--> <div class="President_bg"> <div class="President"> <#set data="channel" model="zcjy" where="title='总裁寄语'" /> <h1 class="biaot"><a href="#">${zcjy.title}</a></h1> <div class="Message_box"> <div class="Message"> <#foreach list="content" model="con" where="channel.title='总裁寄语'" page="1" pageSize="3" > <#if ${con.curPageSort}==1> <div class="j${con.curPageSort}"> <#else> <div class="j${con.curPageSort}" style="display: none;"> <#end if> ${con.contents} </div> <#/foreach> <div class="qh"> <a class="y1 qh_on"></a> <a class="y2"></a> <a class="y3"></a> </div> </div> </div> </div> </div> <!--总裁寄语结束--> <!--合作伙伴开始--> <div class="Partner_bg"> <div class="Partner"> <h3>合作伙伴</h3> <#foreach list="links" model="lk" where="type=2 and siteId=1" > <a href="${lk.linkUrl}" target="_blank">${lk.title}</a> <#/foreach> </div> </div> <!--合作伙伴结束--> <!--底部开始--> <div class="cai_bg"></div> <div class="Web_Icon"></div> <!--底部结束--> <div class="copyright_bottom"> ${site.copyright}<br /> 备案号:${site.siteRecord} </div> <div style="display: none;"> ${site.statScript} </div> </body> </html>
rootmenu.html页面:
<div class="pad-nav"> <span></span> <ul> <!--主菜单--> <#foreach list="channel" model="rootMenu" where="channel.siteId=${site.id} and channel.level=1" > <li><#if ${rootMenu.sort}=="1"> <#if ${channel.id}==0> <a href="index.html" class="cpselect" onclick="showPhoneSubMenu('${rootMenu.title}')">${rootMenu.title}</a> <#else> <a href="index.html" onclick="showPhoneSubMenu('${rootMenu.title}')">${rootMenu.title}</a> <#end if> <#else> <#if ${rootMenu.listType}=="5"> <#if ${rootMenu.id}=="${parentChannel.id}"> <a href="#" class="cpselect" onclick="showPhoneSubMenu('${rootMenu.title}')">${rootMenu.title}</a> <#else> <a href="#" onclick="showPhoneSubMenu('${rootMenu.title}')">${rootMenu.title}</a> <#end if> <#else> <#if ${rootMenu.id}=="${parentChannel.id}"> <a href="/${site.folder}/list${rootMenu.id}.html" class="cpselect" onclick="showPhoneSubMenu('${rootMenu.title}')">${rootMenu.title}</a> <#else> <a href="/${site.folder}/list${rootMenu.id}.html" onclick="showPhoneSubMenu('${rootMenu.title}')">${rootMenu.title}</a> <#end if> <#end if> <#end if> </li> <#/foreach> </ul> <!--子菜单--> <#foreach list="channel" model="rootMenu" where="channel.siteId=${site.id} and channel.level=1" > <div class="two_nav" phone-menu-title="${rootMenu.title}" style="display: none;"> <ul> <#foreach list="channel" model="subMenu" where="parent.Title='${rootMenu.title}'" > <li><a href="/${site.folder}/list${subMenu.id}.html">${subMenu.title}</a></li> <#/foreach> </ul> </div> <#/foreach> </div> <div class="fl nav"> <ul> <!--主菜单--> <#foreach list="channel" model="rootMenu" where="channel.siteId=${site.id} and channel.level=1" > <li> <#if ${rootMenu.sort}=="1"> <#if ${channel.id}==0> <a href="index.html" class="cur">${rootMenu.title}</a> <#else> <a href="index.html" class="smen">${rootMenu.title}</a> <#end if> <#else> <#if ${rootMenu.listType}=="5"> <#if ${rootMenu.id}=="${parentChannel.id}"> <a href="#" class="cur" onclick="showSubMenu('${rootMenu.title}')">${rootMenu.title}</a> <#else> <a href="#" class="smen" onclick="showSubMenu('${rootMenu.title}')">${rootMenu.title}</a> <#end if> <#else> <#if ${parentChannel.id}==0> <#if ${rootMenu.id}=="${channel.id}"> <a href="/${site.folder}/list${rootMenu.id}.html" class="cur">${rootMenu.title}</a> <#else> <a href="/${site.folder}/list${rootMenu.id}.html" class="smen">${rootMenu.title}</a> <#end if> <#else> <#if ${rootMenu.id}=="${parentChannel.id}"> <a href="/${site.folder}/list${rootMenu.id}.html" class="cur">${rootMenu.title}</a> <#else> <a href="/${site.folder}/list${rootMenu.id}.html" class="smen">${rootMenu.title}</a> <#end if> <#end if> <#end if> <#end if> </li> <#/foreach> </ul> </div>
list.html页面:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta content="width=device-width, minimum-scale=1,initial-scale=1, maximum-scale=1, user-scalable=1;" id="viewport" name="viewport" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="keywords" content="${site.keywords}" /> <meta name="description" content="${site.description}" /> <link href="theme/css/Int.css" rel="stylesheet" /> <link href="theme/css/head.css" rel="stylesheet" /> <link href="theme/css/index.css" rel="stylesheet" /> <link href="theme/css/more.css" rel="stylesheet" /> <script type="text/javascript" src="theme/js/jquery-1.9.1.js"></script> <script type="text/javascript" src="theme/js/layout.js"></script> <script type="text/javascript" src="theme/js/more.js"></script> <!--<script src="js/jquery.superslide.2.1.1.js" type="text/javascript"></script> PC端轮播图JS --> <title>${channel.title}-${parentChannel.title}-${site.siteName}</title> <script type="text/javascript"> </script> <script type="text/javascript"> $(document).ready(function () { var topMain = $(".nav_part").height()//对象的的高度 var nav = $(".nav_part"); $(window).scroll(function () { if ($(window).scrollTop() > topMain) {//如果滚动条顶部的距离大于topMain则就nav导航就添加类.nav_scroll,否则就移除。 nav.addClass("nav_scroll"); } else { nav.removeClass("nav_scroll"); } }); }) </script> </head> <body> <!--头部开始--> <div class="header"> <div class="w"> <div class="fl logo"> <a href="index.html"> <img src="theme/images/logo.png"> </a> </div> <div class="sj_language"> <#if ${site.id}=="1"> <a href="/en/index.html"><em class="china" style="background: url(theme/images/eng.jpg) left center no-repeat;">English</em><i style="background: url(theme/images/china.jpg) left center no-repeat;">中文版</i></a> <#else> <a href="/cn/index.html"><em class="china">中文版</em><i>English</i></a> <#end if> </div> <!--主菜单--> <#include src="/templates/${site.folder}/rootmenu.html" /> <div class="language"> <#if ${site.id}=="1"> <a href="/en/index.html"><span class="china" style="background: url(theme/images/eng.jpg) left center no-repeat;">English</span><i style="background: url(theme/images/china.jpg) left center no-repeat;">中文版</i></a> <#else> <a href="/cn/index.html"><span class="china">中文版</span><i>English</i></a> <#end if> </div> <div class="clear"></div> </div> <div class="clear"></div> <!--子菜单--> <#include src="/templates/${site.folder}/submenu.html" /> <!--头部结束--> <!--广告图开始--> <div class="gg_pic"> <img src="theme/images/ejbg.jpg" /> </div> <!--广告图结束--> <!--内容区域开始--> <div class="Main_part"> <!--左侧导航开始--> <#include src="/templates/${site.folder}/leftmenu.html" /> <!--左侧导航结束--> <!--右侧内容开始--> <div class="nr_part"> <div class="position"> <span class="fl">${channel.title}</span> <span class="fr">当前位置:<a href="#"><#if ${parentChannel.id}!=0>${parentChannel.title}><#end if>${channel.title}</a></span> </div> <div class="Media_Focus"> <h1 class="jujiao"> <del> <img alt="" src="${channel.iconUrl}" /></del> ${channel.title}</h1> <ul> <#foreach main="true" list="content" model="con" channel="${channel.id}" page="${pager.page}" pageSize="10" > <li> <label>[${channel.title}]</label><a href="/${site.folder}/content${con.id}.html">${con.title}</a><span>${con.publishTime}</span></li> <#/foreach> </ul> <div class="pag"> <#if ${pager.prePage}==1> <a href="list${channel.id}.html" onclick="">上一页</a> <#else> <a href="list${channel.id}-${pager.prePage}.html" onclick="">上一页</a> <#end if> <span style="margin-right: 40px; font-size: 12px; color: #666;">${pager.page} / ${pager.pageCount}</span> <#if ${pager.nextPage}==1> <a href="list${channel.id}.html">下一页</a> <#else> <a href="list${channel.id}-${pager.nextPage}.html">下一页</a> <#end if> </div> </div> </div> <!--右侧内容结束--> </div> <!--内容结束--> <!--合作伙伴开始--> <div class="Partner_bg"> <div class="Partner"> <h3>合作伙伴</h3> <#foreach list="links" model="lk" where="type=2 and siteId=1" > <a href="${lk.linkUrl}" target="_blank">${lk.title}</a> <#/foreach> </div> </div> <!--合作伙伴结束-- <!--底部开始--> <div class="cai_bg"></div> <div class="Web_Icon"></div> <!--底部结束--> <!--<iframe src="footer.html" width="100%" height="365" frameborder="0" scrolling="no"></iframe>--> <div class="copyright_bottom"> ${site.copyright}<br /> 备案号:${site.siteRecord} </div> <div style="display: none;"> ${site.statScript} </div> </body> </html>
模板引擎代码如下:
Tag类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DAL.Parser { /// <summary> /// 标签 /// </summary> public class Tag { /// <summary> /// 标签开始位置 /// </summary> public int start { get; set; } /// <summary> /// 标签标记 /// </summary> public Token token { get; set; } /// <summary> /// 标签字符串 /// </summary> public string tagStr { get; set; } /// <summary> /// 标签字符串长度 /// </summary> public int length { get { return tagStr.Length; } } /// <summary> /// 标签结束位置 /// </summary> public int end { get { return start + length; } } /// <summary> /// 标签 /// </summary> /// <param name="start">标签开始位置</param> /// <param name="token">标签标记</param> /// <param name="tagStr">标签字符串</param> public Tag(int start, Token token, string tagStr) { this.start = start; this.token = token; this.tagStr = tagStr; } } }
Token类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DAL.Parser { /// <summary> /// 标签标记 /// </summary> public enum Token { /// <summary> /// 标签开始 /// </summary> TagStart, /// <summary> /// 标签结束 /// </summary> TagEnd, /// <summary> /// else标签 /// </summary> ElseTag } }
IfTag类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace DAL.Parser { /// <summary> /// if标签 /// </summary> public class IfTag { /// <summary> /// 开始标签 /// </summary> public Tag startIf { get; set; } /// <summary> /// else标签,可为null /// </summary> public Tag elseTag { get; set; } /// <summary> /// 结束标签 /// </summary> public Tag endIf { get; set; } /// <summary> /// 页面html /// </summary> public string pageHtml { get; set; } /// <summary> /// if分支html /// </summary> public string ifHtml { get { if (elseTag != null) { return pageHtml.Substring(startIf.start + startIf.length, elseTag.start - startIf.start - startIf.length); } else { return pageHtml.Substring(startIf.start + startIf.length, endIf.start - startIf.start - startIf.length); } } } /// <summary> /// else分支html /// </summary> public string elseHtml { get { if (elseTag != null && elseTag.start + elseTag.length < endIf.start) { return pageHtml.Substring(elseTag.start + elseTag.length, endIf.start - elseTag.start - elseTag.length); } else { return string.Empty; } } } /// <summary> /// 结果html /// </summary> public string resultHtml { get; set; } /// <summary> /// if标签 /// </summary> /// <param name="startIf">开始标签</param> /// <param name="elseTag">else标签</param> /// <param name="endIf">结束标签</param> /// <param name="pageHtml">页面html</param> public IfTag(Tag startIf, Tag elseTag, Tag endIf, string pageHtml) { this.startIf = startIf; this.endIf = endIf; this.elseTag = elseTag; this.pageHtml = pageHtml; this.resultHtml = string.Empty; if (!Regex.IsMatch(startIf.tagStr, @"${([^${}]+).([^${}]+)}")) //如果没有未解析的Model { bool compareOr = false; foreach (string strOr in startIf.tagStr.Replace("<#if", "").Replace(">", "").Split(new string[] { " or " }, StringSplitOptions.RemoveEmptyEntries)) //遍历or分隔 { bool compareAnd = true; foreach (string strAnd in strOr.Split(new string[] { " and " }, StringSplitOptions.RemoveEmptyEntries)) //遍历and分隔 { Regex reg = new Regex(@"([^s]*)[s]*(==|!=|大于|小于)[s]*([^s]*)", RegexOptions.IgnoreCase); MatchCollection mc = reg.Matches(strAnd); foreach (Match match in mc) { #region 比较 switch (match.Groups[2].Value) { case "==": if (match.Groups[1].Value.Replace(""", "") != match.Groups[3].Value.Replace(""", "")) { compareAnd = false; } break; case "!=": if (match.Groups[1].Value.Replace(""", "") == match.Groups[3].Value.Replace(""", "")) { compareAnd = false; } break; case "大于": int d; if (int.TryParse(match.Groups[1].Value, out d) && int.TryParse(match.Groups[3].Value, out d)) { if (Convert.ToInt32(match.Groups[1].Value.Replace(""", "")) <= Convert.ToInt32(match.Groups[3].Value.Replace(""", ""))) { compareAnd = false; } } break; case "小于": if (int.TryParse(match.Groups[1].Value, out d) && int.TryParse(match.Groups[3].Value, out d)) { if (Convert.ToInt32(match.Groups[1].Value.Replace(""", "")) >= Convert.ToInt32(match.Groups[3].Value.Replace(""", ""))) { compareAnd = false; } } break; default: break; } #endregion } } // end //遍历and分隔 if (compareAnd) { compareOr = true; } } // end //遍历or分隔 if (compareOr) { resultHtml = ifHtml; return; } resultHtml = elseHtml; } } //end 构造函数 } //end IfTag 类 } //end namespace
ForeachTag类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using Models; namespace DAL.Parser { /// <summary> /// Foreach标签 /// </summary> public class ForeachTag { /// <summary> /// 开始标签 /// </summary> public Tag startForeach { get; set; } /// <summary> /// 结束标签 /// </summary> public Tag endForeach { get; set; } /// <summary> /// 标签内html /// </summary> public string innerHtml { get { return pageHtml.Substring(startForeach.start + startForeach.length, endForeach.start - startForeach.start - startForeach.length); } } /// <summary> /// 页面html /// </summary> public string pageHtml { get; set; } /// <summary> /// 列表的标识 /// </summary> public string list { get; set; } /// <summary> /// 列表的model /// </summary> public string model { get; set; } /// <summary> /// where /// </summary> public string where { get; set; } /// <summary> /// 当面页数 /// </summary> public int page { get; set; } /// <summary> /// 每页数据条数 /// </summary> public int pageSize { get; set; } /// <summary> /// 该foreach是否是当前页面的主列表 /// </summary> public bool main = false; /// <summary> /// 栏目名称或栏目ID /// </summary> public string channel { get; set; } /// <summary> /// Foreach标签 /// </summary> /// <param name="startForeach">开始标签</param> /// <param name="endForeach">结束标签</param> /// <param name="pageHtml">页面html</param> public ForeachTag(Tag startForeach, Tag endForeach, string pageHtml) { this.startForeach = startForeach; this.endForeach = endForeach; this.pageHtml = pageHtml; Regex reg = new Regex(@"([^s]+)s*=s*""([^""]+)""", RegexOptions.IgnoreCase); MatchCollection mc = reg.Matches(startForeach.tagStr); foreach (Match m in mc) { switch (m.Groups[1].Value) { case "list": this.list = m.Groups[2].Value; break; case "model": this.model = m.Groups[2].Value; break; case "where": this.where = m.Groups[2].Value; break; case "page": if (Regex.IsMatch(m.Groups[2].Value, @"^d+$")) { this.page = Convert.ToInt32(m.Groups[2].Value); } break; case "pageSize": if (Regex.IsMatch(m.Groups[2].Value, @"^d+$")) { this.pageSize = Convert.ToInt32(m.Groups[2].Value); } break; case "channel": this.channel = m.Groups[2].Value; break; case "main": this.main = true; break; } } } // end 构造函数 } // end ForeachTag 类 } // end namespace
PageNum类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DAL.Parser { /// <summary> /// 分页数字类 /// </summary> public class PageNum { /// <summary> /// 分页数字 /// </summary> public int num { get; set; } /// <summary> /// 是否非数字,1:非数字,0数字,用来显示省略号 /// </summary> public int nan { get; set; } /// <summary> /// 分页数字 /// </summary> /// <param name="num">分页数字</param> /// <param name="nan">是否非数字,1:非数字,0数字,用来显示省略号</param> public PageNum(int num, int nan = 0) { this.num = num; this.nan = nan; } } }
模板引擎TemplateDal类:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Web; using DAL.Parser; using Models; namespace DAL { /// <summary> /// 模板引擎 /// </summary> public class TemplateDal { #region 变量 /// <summary> /// 分页数字列表 /// </summary> public static List<PageNum> pageNumList = null; #endregion #region 载入模板 /// <summary> /// 载入模板 /// </summary> public static string LoadTemplate(HttpServerUtilityBase server, string url) { string result = string.Empty; StreamReader sr = new StreamReader(server.MapPath(url), Encoding.UTF8); result = sr.ReadToEnd(); sr.Close(); return result; } #endregion #region 写入模板 /// <summary> /// 写入模板 /// </summary> public static void WriteTemplate(HttpServerUtilityBase server, string url, string html) { string result = string.Empty; string path = server.MapPath(url); if (!Directory.Exists(Path.GetDirectoryName(path))) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fs, Encoding.UTF8); sw.Write(html); sw.Close(); fs.Close(); } #endregion #region 替换页面model /// <summary> /// 替换页面model /// </summary> public static string ReplaceModels(string pageHtml, Dictionary<string, object> data) { Regex reg = new Regex(@"${([^${}]+).([^${}]+)}", RegexOptions.IgnoreCase); MatchCollection mc = reg.Matches(pageHtml); foreach (Match m in mc) { if (data.Keys.Contains<string>(m.Groups[1].Value)) { object model = data[m.Groups[1].Value]; Type type = model.GetType(); PropertyInfo propertyInfo = type.GetProperty(m.Groups[2].Value); object obj = propertyInfo.GetValue(model, null); string val = string.Empty; if (obj != null) { if (obj.GetType() == typeof(DateTime)) { val = ((DateTime)obj).ToString("yyyy-MM-dd"); } else { val = obj.ToString(); } } pageHtml = pageHtml.Replace("${" + m.Groups[1].Value + "." + m.Groups[2].Value + "}", val); } } return pageHtml; } #endregion #region 替换列表的model /// <summary> /// 替换列表的model /// </summary> public static string ReplaceModels(string html, string model, object data) { Regex reg = new Regex(@"${[^${}]+.([^${}]+)}", RegexOptions.IgnoreCase); MatchCollection mc = reg.Matches(html); foreach (Match m in mc) { Type type = data.GetType(); PropertyInfo propertyInfo = type.GetProperty(m.Groups[1].Value); object obj = propertyInfo.GetValue(data, null); string val = string.Empty; if (obj != null) { if (obj.GetType() == typeof(DateTime)) { val = ((DateTime)obj).ToString("yyyy-MM-dd"); } else { val = obj.ToString(); } } html = html.Replace("${" + model + "." + m.Groups[1].Value + "}", val); } return html; } #endregion #region 判断页面是否存在 foreach 标签 /// <summary> /// 判断页面是否存在 foreach 标签 /// </summary> public static bool HasForeach(string html) { Regex reg = new Regex(@"<!--[s]{0,1}#[s]{0,1}foreach[s]+[^<>${}]*-->", RegexOptions.IgnoreCase | RegexOptions.Singleline); return reg.IsMatch(html); } #endregion #region 替换foreach /// <summary> /// 替换foreach /// </summary> public static string ReplaceLists(string pageHtml, Dictionary<string, object> data) { #region 生成标签集合 Regex regStartForeach = new Regex(@"<!--[s]{0,1}#[s]{0,1}foreach[s]+[^<>]*>", RegexOptions.IgnoreCase | RegexOptions.Singleline); Regex regEndForeach = new Regex(@"<!--[s]{0,1}#[s]{0,1}/foreach[s]{0,1}-->", RegexOptions.IgnoreCase | RegexOptions.Singleline); MatchCollection mcStartForeach = regStartForeach.Matches(pageHtml); MatchCollection mcEndForeach = regEndForeach.Matches(pageHtml); List<Tag> tagList = new List<Tag>(); foreach (Match mStartForeach in mcStartForeach) { Tag tag = new Tag(mStartForeach.Index, Token.TagStart, mStartForeach.Value); tagList.Add(tag); } foreach (Match mEndForeach in mcEndForeach) { Tag tag = new Tag(mEndForeach.Index, Token.TagEnd, mEndForeach.Value); tagList.Add(tag); } tagList.Sort((a, b) => a.start - b.start); #endregion for (int i = 0; i < tagList.Count; i++) //遍历标签集合 { Tag tag = tagList[i]; int depth = 0; if (tag.token == Token.TagStart) { for (int j = i + 1; j < tagList.Count; j++) { if (tagList[j].token == Token.TagEnd && depth == 0) { string resultHtml = string.Empty; ForeachTag foreachTag = new ForeachTag(tag, tagList[j], pageHtml); #region 替换 switch (foreachTag.list) { case "channel": StringBuilder sb = new StringBuilder(); ChannelDal m_ChannelDal = new ChannelDal(); List<cms_channel_ext> channelList = m_ChannelDal.GetList(foreachTag.where); foreach (cms_channel_ext channel in channelList) { sb.Append(TemplateDal.ReplaceModels(foreachTag.innerHtml, foreachTag.model, channel)); } resultHtml = foreachTag.pageHtml.Substring(0, foreachTag.startForeach.start) + sb.ToString() + foreachTag.pageHtml.Substring(foreachTag.endForeach.start + foreachTag.endForeach.length); break; case "content": sb = new StringBuilder(); ContentDal m_ContentDal = new ContentDal(); PagerModel pager = new PagerModel(); pager.rows = foreachTag.pageSize; pager.page = foreachTag.page; List<cms_content_ext> contentList = m_ContentDal.GetList(ref pager, foreachTag.channel, foreachTag.where); foreach (cms_content_ext content in contentList) { sb.Append(TemplateDal.ReplaceModels(foreachTag.innerHtml, foreachTag.model, content)); } resultHtml = foreachTag.pageHtml.Substring(0, foreachTag.startForeach.start) + sb.ToString() + foreachTag.pageHtml.Substring(foreachTag.endForeach.start + foreachTag.endForeach.length); break; case "links": sb = new StringBuilder(); LinksDal m_LinksDal = new LinksDal(); List<cms_links_ext> linksList = m_LinksDal.GetList(foreachTag.where); foreach (cms_links_ext links in linksList) { sb.Append(TemplateDal.ReplaceModels(foreachTag.innerHtml, foreachTag.model, links)); } resultHtml = foreachTag.pageHtml.Substring(0, foreachTag.startForeach.start) + sb.ToString() + foreachTag.pageHtml.Substring(foreachTag.endForeach.start + foreachTag.endForeach.length); break; case "banners": sb = new StringBuilder(); BannersDal m_BannersDal = new BannersDal(); List<cms_banners_ext> bannersList = m_BannersDal.GetList(foreachTag.where); foreach (cms_banners_ext banners in bannersList) { sb.Append(TemplateDal.ReplaceModels(foreachTag.innerHtml, foreachTag.model, banners)); } resultHtml = foreachTag.pageHtml.Substring(0, foreachTag.startForeach.start) + sb.ToString() + foreachTag.pageHtml.Substring(foreachTag.endForeach.start + foreachTag.endForeach.length); break; case "pages": if (data.ContainsKey(foreachTag.list)) { sb = new StringBuilder(); List<PageNum> pageNumList = data[foreachTag.list] as List<PageNum>; foreach (PageNum pageNum in pageNumList) { sb.Append(TemplateDal.ReplaceModels(foreachTag.innerHtml, foreachTag.model, pageNum)); } resultHtml = foreachTag.pageHtml.Substring(0, foreachTag.startForeach.start) + sb.ToString() + foreachTag.pageHtml.Substring(foreachTag.endForeach.start + foreachTag.endForeach.length); } break; default: resultHtml = foreachTag.pageHtml.Substring(0, foreachTag.startForeach.start) + foreachTag.pageHtml.Substring(foreachTag.endForeach.start + foreachTag.endForeach.length); break; } #endregion return resultHtml; } if (tagList[j].token == Token.TagStart) { depth++; } if (tagList[j].token == Token.TagEnd) { depth--; } } } } return pageHtml; } #endregion #region 判断页面是否存在 if else 标签 /// <summary> /// 判断页面是否存在 if else 标签 /// </summary> public static bool HasIfElse(string html) { Regex reg = new Regex(@"<!--[s]{0,1}#[s]{0,1}if[s]+([^<>${}]+)[s]*-->", RegexOptions.IgnoreCase); return reg.IsMatch(html); } #endregion #region 替换 if else end if /// <summary> /// 替换 if else end if /// </summary> public static string ReplaceIfElse(string pageHtml) { #region 生成标签集合 Regex regStartIf = new Regex(@"<!--[s]{0,1}#[s]{0,1}if[s]+([^<>]+)[s]*-->", RegexOptions.IgnoreCase | RegexOptions.Singleline); Regex regElseTag = new Regex(@"<!--[s]{0,1}#[s]{0,1}else[s]{0,1}-->", RegexOptions.IgnoreCase | RegexOptions.Singleline); Regex regEndIf = new Regex(@"<!--[s]{0,1}#[s]{0,1}end if[s]{0,1}-->", RegexOptions.IgnoreCase | RegexOptions.Singleline); MatchCollection mcStartIf = regStartIf.Matches(pageHtml); MatchCollection mcElseTag = regElseTag.Matches(pageHtml); MatchCollection mcEndIf = regEndIf.Matches(pageHtml); List<Tag> tagList = new List<Tag>(); foreach (Match mStartIf in mcStartIf) { Tag tag = new Tag(mStartIf.Index, Token.TagStart, mStartIf.Value); tagList.Add(tag); } foreach (Match mEndIf in mcEndIf) { Tag tag = new Tag(mEndIf.Index, Token.TagEnd, mEndIf.Value); tagList.Add(tag); } foreach (Match mElseTag in mcElseTag) { Tag tag = new Tag(mElseTag.Index, Token.ElseTag, mElseTag.Value); tagList.Add(tag); } tagList.Sort((a, b) => a.start - b.start); #endregion for (int i = 0; i < tagList.Count; i++) //遍历标签集合 { Tag tagStartIf = tagList[i]; Tag tagElseTag = null; int depth = 0; if (tagStartIf.token == Token.TagStart) //是if标签 { for (int j = i + 1; j < tagList.Count; j++) //遍历if标签后面的标签 { if (depth == 0) { if (tagList[j].token == Token.ElseTag) //是else标签 { tagElseTag = tagList[j]; } if (tagList[j].token == Token.TagEnd) { IfTag ifTag = new IfTag(tagStartIf, tagElseTag, tagList[j], pageHtml); if (!Regex.IsMatch(ifTag.startIf.tagStr, @"${([^${}]+).([^${}]+)}")) //如果没有未解析的Model { return pageHtml.Substring(0, ifTag.startIf.start) + ifTag.resultHtml + pageHtml.Substring(ifTag.endIf.start + ifTag.endIf.length); } } } if (tagList[j].token == Token.TagStart) { depth++; } if (tagList[j].token == Token.TagEnd) { depth--; } } } } return pageHtml; } #endregion #region 替换页面function /// <summary> /// 替换页面function /// </summary> public static string ReplaceFunctions(string pageHtml) { #region 替换cutstr函数 Regex reg = new Regex(@"${cutstr((.*),([d]+))}", RegexOptions.IgnoreCase); MatchCollection mc = reg.Matches(pageHtml); foreach (Match m in mc) { Regex reg2 = new Regex(@"(?:<[^<>]+[s]+[^<>]+[s]*/>)|(?:<[^<>]+[s]+[^<>]+[s]*>)|(?:</[^<>]+>)|(?: )", RegexOptions.IgnoreCase); string html = reg2.Replace(m.Groups[1].Value, ""); if (html.Length > Convert.ToInt32(m.Groups[2].Value)) { pageHtml = pageHtml.Replace(m.Value, html.Substring(0, Convert.ToInt32(m.Groups[2].Value))); } else { pageHtml = pageHtml.Replace(m.Value, html); } } #endregion #region 替换html2text函数 reg = new Regex(@"${html2text((.+),([d]+))}", RegexOptions.IgnoreCase); mc = reg.Matches(pageHtml); foreach (Match m in mc) { Regex reg2 = new Regex(@"(?:<[^<>]+[s]+[^<>]+[s]*/>)|(?:<[^<>]+[s]+[^<>]+[s]*>)|(?:</[^<>]+>)|(?: )", RegexOptions.IgnoreCase); string html = reg2.Replace(m.Groups[1].Value, ""); pageHtml = pageHtml.Replace(m.Value, html); } #endregion #region 替换replace函数 reg = new Regex(@"${replace(([^(),]+),([^(),]+),([^(),]+))}", RegexOptions.IgnoreCase); mc = reg.Matches(pageHtml); foreach (Match m in mc) { pageHtml = pageHtml.Replace(m.Value, m.Groups[1].Value.Replace(m.Groups[2].Value.Replace("'", ""), m.Groups[3].Value.Replace("'", ""))); } #endregion return pageHtml; } #endregion #region 替换页面include /// <summary> /// 替换页面include /// </summary> public static string ReplaceIncludes(HttpServerUtilityBase server, string pageHtml) { Regex reg = new Regex(@"<!--[s]{0,1}#[s]{0,1}include[s]+src[s]*=[s]*""([^""<>${}]+)""[s]*-->", RegexOptions.IgnoreCase); MatchCollection mc = reg.Matches(pageHtml); foreach (Match m in mc) { StreamReader sr = new StreamReader(server.MapPath(m.Groups[1].Value), Encoding.UTF8); string html = sr.ReadToEnd(); sr.Close(); pageHtml = pageHtml.Replace(m.Value, html); } return pageHtml; } #endregion #region 替换页面set /// <summary> /// 替换页面set /// </summary> public static string ReplaceSets(string pageHtml) { Regex reg = new Regex(@"<!--[s]{0,1}#[s]{0,1}set[s]+([^<>]+)[s]*-->", RegexOptions.IgnoreCase); MatchCollection mc = reg.Matches(pageHtml); foreach (Match m in mc) { Regex regSub = new Regex(@"([^s]+)s*=s*""([^""]+)""", RegexOptions.IgnoreCase); MatchCollection mcSub = regSub.Matches(m.Groups[1].Value); string data = string.Empty; string model = string.Empty; string where = string.Empty; foreach (Match mSub in mcSub) { switch (mSub.Groups[1].Value) { case "data": data = mSub.Groups[2].Value; break; case "model": model = mSub.Groups[2].Value; break; case "where": where = mSub.Groups[2].Value; break; } } switch (data) { case "channel": ChannelDal m_ChannelDal = new ChannelDal(); cms_channel channel = m_ChannelDal.Get(where); Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add(model, channel); pageHtml = pageHtml.Replace(m.Value, ""); pageHtml = TemplateDal.ReplaceModels(pageHtml, dic); break; } } return pageHtml; } #endregion #region 获取head内容 /// <summary> /// 获取head内容 /// </summary> public static string GetHeadHtml(string pageHtml) { Regex reg = new Regex(@"<head>([Ss]*)</head>", RegexOptions.IgnoreCase); Match m = reg.Match(pageHtml); return m.Groups[1].Value; } #endregion #region 获取body内容 /// <summary> /// 获取body内容 /// </summary> public static string GetBodyHtml(string pageHtml) { Regex reg = new Regex(@"<body>([Ss]*)</body>", RegexOptions.IgnoreCase); Match m = reg.Match(pageHtml); return m.Groups[1].Value; } #endregion #region 获取一个ForeachTag /// <summary> /// 获取一个ForeachTag /// </summary> public static ForeachTag GetForeachTag(string pageHtml, string list = "content") { #region 生成标签集合 Regex regStartForeach = new Regex(@"<!--[s]{0,1}#[s]{0,1}foreach[s]+[^<>]*-->", RegexOptions.IgnoreCase | RegexOptions.Singleline); Regex regEndForeach = new Regex(@"<!--[s]{0,1}#[s]{0,1}/foreach[s]{0,1}-->", RegexOptions.IgnoreCase | RegexOptions.Singleline); MatchCollection mcStartForeach = regStartForeach.Matches(pageHtml); MatchCollection mcEndForeach = regEndForeach.Matches(pageHtml); List<Tag> tagList = new List<Tag>(); foreach (Match mStartForeach in mcStartForeach) { Tag tag = new Tag(mStartForeach.Index, Token.TagStart, mStartForeach.Value); tagList.Add(tag); } foreach (Match mEndForeach in mcEndForeach) { Tag tag = new Tag(mEndForeach.Index, Token.TagEnd, mEndForeach.Value); tagList.Add(tag); } tagList.Sort((a, b) => a.start - b.start); #endregion for (int i = 0; i < tagList.Count; i++) //遍历标签集合 { Tag tag = tagList[i]; int depth = 0; if (tag.token == Token.TagStart) { for (int j = i + 1; j < tagList.Count; j++) { if (tagList[j].token == Token.TagEnd && depth == 0) { ForeachTag foreachTag = new ForeachTag(tag, tagList[j], pageHtml); if (foreachTag.main && foreachTag.list == list) { return foreachTag; } } if (tagList[j].token == Token.TagStart) { depth++; } if (tagList[j].token == Token.TagEnd) { depth--; } } } } //end 遍历标签集合 return null; } #endregion } //end of class TemplateDal } //end of namespace DAL
使用模板引擎生成静态页面:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Web; using System.Web.Mvc; using System.Web.Script.Serialization; using Common; using Common.Utils; using DAL; using DAL.Parser; using DBHelper; using Models; namespace NetCMS.Web.Areas.Admin.Controllers { /// <summary> /// 前台更新 /// </summary> public class FrontPageManageController : Common.ControllerBase { #region 变量 private SiteDal m_SiteDal = new SiteDal(); private ChannelDal m_ChannelDal = new ChannelDal(); private ContentDal m_ContentDal = new ContentDal(); /// <summary> /// 进度总数 /// </summary> private static double total = 0; /// <summary> /// 当前进度 /// </summary> private static int cur = 0; /// <summary> /// 错误信息 /// </summary> private static string errMsg = string.Empty; #endregion #region 替换 /// <summary> /// 替换 /// </summary> private string Replace(string templateHtml, Dictionary<string, object> dic) { templateHtml = TemplateDal.ReplaceSets(templateHtml); templateHtml = TemplateDal.ReplaceModels(templateHtml, dic); templateHtml = TemplateDal.ReplaceIncludes(Server, templateHtml); templateHtml = TemplateDal.ReplaceModels(templateHtml, dic); while (TemplateDal.HasIfElse(templateHtml)) { templateHtml = TemplateDal.ReplaceIfElse(templateHtml); } while (TemplateDal.HasForeach(templateHtml)) { templateHtml = TemplateDal.ReplaceLists(templateHtml, dic); } while (TemplateDal.HasIfElse(templateHtml)) { templateHtml = TemplateDal.ReplaceIfElse(templateHtml); } templateHtml = TemplateDal.ReplaceFunctions(templateHtml); string headHtml = TemplateDal.GetHeadHtml(templateHtml); string bodyHtml = TemplateDal.GetBodyHtml(templateHtml); StringBuilder sb = new StringBuilder(); sb.AppendFormat("<!DOCTYPE html> <html> <head> {0} </head> <body> {1} </body> </html> ", headHtml, bodyHtml); return sb.ToString(); } #endregion #region Index页面 [Permission(Code = "Index")] public ActionResult Index() { return View(); } #endregion #region Update更新 [HttpPost] [Permission(Code = "Index")] public ActionResult Update() { try { new Thread(new ThreadStart(delegate() { try { UpdateTheme(); UpdateIndex(); UpdateError(); UpdateComments(); } catch (Exception ex) { errMsg += ex.Message + "<br />" + ex.StackTrace.Replace(" ", "<br />"); } })).Start(); new Thread(new ThreadStart(delegate() { try { UpdateList(); } catch (Exception ex) { errMsg += ex.Message + "<br />" + ex.StackTrace.Replace(" ", "<br />"); } })).Start(); new Thread(new ThreadStart(delegate() { try { UpdateContent(); } catch (Exception ex) { errMsg += ex.Message + "<br />" + ex.StackTrace.Replace(" ", "<br />"); } })).Start(); return Content("OK"); } catch (Exception ex) { return Content(ex.Message); } } #endregion #region 更新theme /// <summary> /// 更新theme /// </summary> public void UpdateTheme() { List<cms_site_ext> siteList = m_SiteDal.GetListAll(); foreach (cms_site_ext site in siteList) //遍历站点 { string fromPath = Server.MapPath(string.Format("/templates/{0}/theme/", site.folder)); string toPath = Server.MapPath(string.Format("/{0}/theme/", site.folder)); CopyThemeFiles(fromPath, toPath); } cur++; } /// <summary> /// 更新theme中的文件 /// </summary> private void CopyThemeFiles(string fromPath, string toPath) { if (!Directory.Exists(toPath)) { Directory.CreateDirectory(toPath); } foreach (string filePath in Directory.GetFiles(fromPath)) { System.IO.File.Copy(filePath, toPath + Path.GetFileName(filePath), true); } foreach (string dirPath in Directory.GetDirectories(fromPath)) { int pos = dirPath.LastIndexOf("\"); CopyThemeFiles(dirPath, toPath + dirPath.Substring(pos + 1) + "\"); } } #endregion #region 更新index页面 /// <summary> /// 更新index页面 /// </summary> public void UpdateIndex() { List<cms_site_ext> siteList = m_SiteDal.GetListAll(); int i = 0; foreach (cms_site_ext site in siteList) //遍历站点 { string templateHtml = TemplateDal.LoadTemplate(Server, string.Format("/templates/{0}/index.html", site.folder)); Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("site", site); dic.Add("parentParentChannel", new cms_channel()); dic.Add("parentChannel", new cms_channel()); dic.Add("channel", new cms_channel()); TemplateDal.WriteTemplate(Server, string.Format("/{0}/index.html", site.folder), Replace(templateHtml, dic)); if (i++ == 0) { string fromPath = Server.MapPath(string.Format("/templates/{0}/theme/", site.folder)); string toPath = Server.MapPath(string.Format("/theme/", site.folder)); CopyThemeFiles(fromPath, toPath); TemplateDal.WriteTemplate(Server, "/index.html", Replace(templateHtml, dic)); } } cur++; } #endregion #region 更新list页面 /// <summary> /// 更新list页面 /// </summary> public void UpdateList() { List<cms_site_ext> siteList = m_SiteDal.GetListAll(); foreach (cms_site_ext site in siteList) //遍历站点 { List<cms_channel_ext> channelList = m_ChannelDal.GetList(string.Format("channel.siteId={0}", site.id)); foreach (cms_channel_ext channel in channelList) //遍历栏目 { if (!string.IsNullOrWhiteSpace(errMsg)) break; //有错误则跳出 #region 获取父栏目 cms_channel parentParentChannel; cms_channel parentChannel; if (channel.parentId == -1) { parentChannel = new cms_channel(); parentChannel.parentId = -1; } else { parentChannel = m_ChannelDal.Get(channel.parentId); } if (parentChannel.parentId == -1) { parentParentChannel = new cms_channel(); parentParentChannel.parentId = -1; } else { parentParentChannel = m_ChannelDal.Get(parentChannel.parentId); } #endregion if (channel.listType == (int)Enums.ChannelListType.文字列表 || channel.listType == (int)Enums.ChannelListType.图片列表 || channel.listType == (int)Enums.ChannelListType.父级栏目) { #region 取模板 string templateFileName = string.IsNullOrWhiteSpace(channel.template) ? "list.html" : channel.template; string templateHtml = TemplateDal.LoadTemplate(Server, string.Format("/templates/{0}/list/{1}", site.folder, templateFileName)); #endregion #region 设置分页参数 ForeachTag foreachTag = TemplateDal.GetForeachTag(templateHtml); PagerModel pager = new PagerModel(); if (foreachTag != null) { pager.rows = foreachTag.pageSize; } else { pager.rows = 20; } pager.page = 1; #endregion do { List<cms_content_ext> contentList = m_ContentDal.GetList(ref pager, channel.id.ToString(), null); Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("site", site); dic.Add("parentParentChannel", parentParentChannel); dic.Add("parentChannel", parentChannel); dic.Add("channel", channel); dic.Add("pager", pager); dic.Add("pages", GetPageList(pager.page, pager.pageCount)); string filePath; if (pager.page == 1) { filePath = string.Format("/{0}/list{1}.html", site.folder, channel.id); TemplateDal.WriteTemplate(Server, filePath, Replace(templateHtml, dic)); } filePath = string.Format("/{0}/list{1}{2}.html", site.folder, channel.id, "-" + pager.page.ToString()); TemplateDal.WriteTemplate(Server, filePath, Replace(templateHtml, dic)); } while (pager.page++ <= pager.pageCount); //遍历每页数据 } if (channel.listType == (int)Enums.ChannelListType.单篇文章) { cms_content content = m_ContentDal.GetByChannelId(channel.id); if (content == null) { StringBuilder sb = new StringBuilder(); sb.Append("<!DOCTYPE html> <html> <head> "); sb.AppendFormat("<script type="text/javascript">window.location = "error.html";</script>"); sb.AppendFormat("</head> <body> </body> </html> "); string filePath = string.Format("/{0}/list{1}.html", site.folder, channel.id); TemplateDal.WriteTemplate(Server, filePath, sb.ToString()); } else { StringBuilder sb = new StringBuilder(); sb.Append("<!DOCTYPE html> <html> <head> "); sb.AppendFormat("<script type="text/javascript">window.location = "/{0}/content{1}.html";</script>", site.folder, content.id); sb.AppendFormat("</head> <body> </body> </html> "); string filePath = string.Format("/{0}/list{1}.html", site.folder, channel.id); TemplateDal.WriteTemplate(Server, filePath, sb.ToString()); } } if (channel.listType == (int)Enums.ChannelListType.页面链接) { string url = string.Empty; if (channel.pageUrl == "comments.html") { url = string.Format("/{0}/{1}", site.folder, channel.pageUrl); } else { url = channel.pageUrl; } StringBuilder sb = new StringBuilder(); sb.Append("<!DOCTYPE html> <html> <head> "); sb.AppendFormat("<script type="text/javascript">window.location = "{0}";</script>", url); sb.AppendFormat("</head> <body> </body> </html> "); string filePath = string.Format("/{0}/list{1}.html", site.folder, channel.id); TemplateDal.WriteTemplate(Server, filePath, sb.ToString()); } cur++; } //end 遍历 channelList } //end 遍历 siteList } #endregion #region 更新单个list页面 /// <summary> /// 更新单个list页面 /// </summary> public ActionResult UpdateListSingle(int id) { try { cms_channel channel = m_ChannelDal.Get(id); cms_site site = m_SiteDal.Get(channel.siteId); #region 获取父栏目 cms_channel parentParentChannel; cms_channel parentChannel; if (channel.parentId == -1) { parentChannel = new cms_channel(); parentChannel.parentId = -1; } else { parentChannel = m_ChannelDal.Get(channel.parentId); } if (parentChannel.parentId == -1) { parentParentChannel = new cms_channel(); parentParentChannel.parentId = -1; } else { parentParentChannel = m_ChannelDal.Get(parentChannel.parentId); } #endregion if (channel.listType == (int)Enums.ChannelListType.文字列表 || channel.listType == (int)Enums.ChannelListType.图片列表 || channel.listType == (int)Enums.ChannelListType.父级栏目) { #region 取模板 string templateFileName = string.IsNullOrWhiteSpace(channel.template) ? "list.html" : channel.template; string templateHtml = TemplateDal.LoadTemplate(Server, string.Format("/templates/{0}/list/{1}", site.folder, templateFileName)); #endregion #region 设置分页参数 ForeachTag foreachTag = TemplateDal.GetForeachTag(templateHtml); PagerModel pager = new PagerModel(); if (foreachTag != null) { pager.rows = foreachTag.pageSize; } else { pager.rows = 20; } pager.page = 1; #endregion do { List<cms_content_ext> contentList = m_ContentDal.GetList(ref pager, channel.id.ToString(), null); Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("site", site); dic.Add("parentParentChannel", parentParentChannel); dic.Add("parentChannel", parentChannel); dic.Add("channel", channel); dic.Add("pager", pager); dic.Add("pages", GetPageList(pager.page, pager.pageCount)); string filePath; if (pager.page == 1) { filePath = string.Format("/{0}/list{1}.html", site.folder, channel.id); TemplateDal.WriteTemplate(Server, filePath, Replace(templateHtml, dic)); } filePath = string.Format("/{0}/list{1}{2}.html", site.folder, channel.id, "-" + pager.page.ToString()); TemplateDal.WriteTemplate(Server, filePath, Replace(templateHtml, dic)); } while (pager.page++ <= pager.pageCount); //遍历每页数据 } if (channel.listType == (int)Enums.ChannelListType.单篇文章) { cms_content content = m_ContentDal.GetByChannelId(channel.id); if (content == null) { StringBuilder sb = new StringBuilder(); sb.Append("<!DOCTYPE html> <html> <head> "); sb.AppendFormat("<script type="text/javascript">window.location = "error.html";</script>"); sb.AppendFormat("</head> <body> </body> </html> "); string filePath = string.Format("/{0}/list{1}.html", site.folder, channel.id); TemplateDal.WriteTemplate(Server, filePath, sb.ToString()); } else { StringBuilder sb = new StringBuilder(); sb.Append("<!DOCTYPE html> <html> <head> "); sb.AppendFormat("<script type="text/javascript">window.location = "/{0}/content{1}.html";</script>", site.folder, content.id); sb.AppendFormat("</head> <body> </body> </html> "); string filePath = string.Format("/{0}/list{1}.html", site.folder, channel.id); TemplateDal.WriteTemplate(Server, filePath, sb.ToString()); } } if (channel.listType == (int)Enums.ChannelListType.页面链接) { string url = string.Empty; if (channel.pageUrl == "comments.html") { url = string.Format("/{0}/{1}", site.folder, channel.pageUrl); } else { url = channel.pageUrl; } StringBuilder sb = new StringBuilder(); sb.Append("<!DOCTYPE html> <html> <head> "); sb.AppendFormat("<script type="text/javascript">window.location = "{0}";</script>", url); sb.AppendFormat("</head> <body> </body> </html> "); string filePath = string.Format("/{0}/list{1}.html", site.folder, channel.id); TemplateDal.WriteTemplate(Server, filePath, sb.ToString()); } var json = new { ok = "OK", url = string.Format("/{0}/list{1}.html", site.folder, channel.id) }; return Json(json); } catch (Exception ex) { var json = new { ok = ex.Message }; return Json(json); } } #endregion #region 更新content页面 /// <summary> /// 更新content页面 /// </summary> public void UpdateContent() { List<cms_content_ext> contentListAll = m_ContentDal.GetListAll(); foreach (cms_content_ext content in contentListAll) //遍历内容详情 { if (!string.IsNullOrWhiteSpace(errMsg)) break; //有错误则跳出 #region 获取下一篇、上一篇、栏目、站点、父栏目等 cms_content_ext nextContent = m_ContentDal.GetNext(content.id); if (nextContent == null) { nextContent = new cms_content_ext(); nextContent.isNull = 1; } cms_content_ext preContent = m_ContentDal.GetPre(content.id); if (preContent == null) { preContent = new cms_content_ext(); preContent.isNull = 1; } cms_channel channel = m_ChannelDal.Get(content.channelId); cms_site site = m_SiteDal.Get(channel.siteId); cms_channel parentParentChannel; cms_channel parentChannel; if (channel.parentId == -1) { parentChannel = new cms_channel(); parentChannel.parentId = -1; } else { parentChannel = m_ChannelDal.Get(channel.parentId); } if (parentChannel.parentId == -1) { parentParentChannel = new cms_channel(); parentParentChannel.parentId = -1; } else { parentParentChannel = m_ChannelDal.Get(parentChannel.parentId); } #endregion if (content.isPageUrl == 1) { string filePath = string.Format("/{0}/content{1}.html", site.folder, content.id); StringBuilder sb = new StringBuilder(); sb.Append("<!DOCTYPE html> <html> <head> "); sb.AppendFormat("<script type="text/javascript">window.location = "{0}";</script>", content.pageUrl); sb.AppendFormat("</head> <body> </body> </html> "); TemplateDal.WriteTemplate(Server, filePath, sb.ToString()); } else { #region 取模板 string templateFileName = string.IsNullOrWhiteSpace(content.template) ? "content.html" : content.template; string templateHtml = TemplateDal.LoadTemplate(Server, string.Format("/templates/{0}/content/{1}", site.folder, templateFileName)); #endregion Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("site", site); dic.Add("parentParentChannel", parentParentChannel); dic.Add("parentChannel", parentChannel); dic.Add("channel", channel); dic.Add("content", content); dic.Add("preContent", preContent); dic.Add("nextContent", nextContent); string filePath = string.Format("/{0}/content{1}.html", site.folder, content.id); TemplateDal.WriteTemplate(Server, filePath, Replace(templateHtml, dic)); } cur++; } } #endregion #region 更新单个content页面 /// <summary> /// 更新单个content页面 /// </summary> public ActionResult UpdateContentSingle(int id) { try { cms_content content = m_ContentDal.Get(id); #region 获取下一篇、上一篇、栏目、站点、父栏目等 cms_content_ext nextContent = m_ContentDal.GetNext(content.id); if (nextContent == null) { nextContent = new cms_content_ext(); nextContent.isNull = 1; } cms_content_ext preContent = m_ContentDal.GetPre(content.id); if (preContent == null) { preContent = new cms_content_ext(); preContent.isNull = 1; } cms_channel channel = m_ChannelDal.Get(content.channelId); cms_site site = m_SiteDal.Get(channel.siteId); cms_channel parentParentChannel; cms_channel parentChannel; if (channel.parentId == -1) { parentChannel = new cms_channel(); parentChannel.parentId = -1; } else { parentChannel = m_ChannelDal.Get(channel.parentId); } if (parentChannel.parentId == -1) { parentParentChannel = new cms_channel(); parentParentChannel.parentId = -1; } else { parentParentChannel = m_ChannelDal.Get(parentChannel.parentId); } #endregion if (content.isPageUrl == 1) { string filePath = string.Format("/{0}/content{1}.html", site.folder, content.id); StringBuilder sb = new StringBuilder(); sb.Append("<!DOCTYPE html> <html> <head> "); sb.AppendFormat("<script type="text/javascript">window.location = "{0}";</script>", content.pageUrl); sb.AppendFormat("</head> <body> </body> </html> "); TemplateDal.WriteTemplate(Server, filePath, sb.ToString()); } else { #region 取模板 string templateFileName = string.IsNullOrWhiteSpace(content.template) ? "content.html" : content.template; string templateHtml = TemplateDal.LoadTemplate(Server, string.Format("/templates/{0}/content/{1}", site.folder, templateFileName)); #endregion Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("site", site); dic.Add("parentParentChannel", parentParentChannel); dic.Add("parentChannel", parentChannel); dic.Add("channel", channel); dic.Add("content", content); dic.Add("preContent", preContent); dic.Add("nextContent", nextContent); string filePath = string.Format("/{0}/content{1}.html", site.folder, content.id); TemplateDal.WriteTemplate(Server, filePath, Replace(templateHtml, dic)); } var json = new { ok = "OK", url = string.Format("/{0}/content{1}.html", site.folder, content.id) }; return Json(json); } catch (Exception ex) { var json = new { ok = ex.Message }; return Json(json); } } #endregion #region 更新error页面 /// <summary> /// 更新error页面 /// </summary> public void UpdateError() { List<cms_site_ext> siteList = m_SiteDal.GetListAll(); foreach (cms_site_ext site in siteList) //遍历站点 { string templateHtml = TemplateDal.LoadTemplate(Server, string.Format("/templates/{0}/error.html", site.folder)); Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("site", site); dic.Add("parentParentChannel", new cms_channel()); dic.Add("parentChannel", new cms_channel()); dic.Add("channel", new cms_channel() { id = -999 }); TemplateDal.WriteTemplate(Server, string.Format("/{0}/error.html", site.folder), Replace(templateHtml, dic)); } cur++; } #endregion #region 更新comments页面 /// <summary> /// 更新comments页面 /// </summary> public void UpdateComments() { List<cms_site_ext> siteList = m_SiteDal.GetListAll(); foreach (cms_site_ext site in siteList) //遍历站点 { List<cms_channel_ext> channelList = m_ChannelDal.GetList(string.Format("channel.siteId={0}", site.id)); cms_channel_ext channel = channelList.Find(a => a.pageUrl == "comments.html"); if (channel != null) { cms_channel parentParentChannel; cms_channel parentChannel; if (channel.parentId == -1) { parentChannel = new cms_channel(); parentChannel.parentId = -1; } else { parentChannel = m_ChannelDal.Get(channel.parentId); } if (parentChannel.parentId == -1) { parentParentChannel = new cms_channel(); parentParentChannel.parentId = -1; } else { parentParentChannel = m_ChannelDal.Get(parentChannel.parentId); } cms_content_ext content = ModelHelper.Convert<cms_content_ext>(m_ContentDal.GetByChannelId(channel.id)); if (content == null) { content = new cms_content_ext(); content.isNull = 1; } string templateHtml = TemplateDal.LoadTemplate(Server, string.Format("/templates/{0}/comments.html", site.folder)); Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("site", site); dic.Add("parentParentChannel", parentParentChannel); dic.Add("parentChannel", parentChannel); dic.Add("channel", channel); dic.Add("content", content); TemplateDal.WriteTemplate(Server, string.Format("/{0}/comments.html", site.folder), Replace(templateHtml, dic)); } } cur++; } #endregion #region GetProcess获取更新进度 [HttpPost] [Permission(Code = "Index")] public ActionResult GetProcess() { try { if (string.IsNullOrWhiteSpace(errMsg)) { if (total == 0) { total = GetTotal(); return Content("0%"); } else { int percent = (int)(cur / total * 100); if (percent == 100) { cur = 0; total = 0; } return Content(string.Format("{0}%", percent)); } } else { return Content("错误:" + errMsg); } } catch (Exception ex) { return Content(ex.Message); } } #endregion #region GetTotal获取进度总数 /// <summary> /// 获取进度总数 /// </summary> /// <returns></returns> public int GetTotal() { int channelCount = m_ChannelDal.GetList(null).Count; int contentCount = m_ContentDal.GetAllCount(); return channelCount + contentCount + 4; } #endregion #region GetPageList生成分页数字列表 /// <summary> /// 生成分页数字列表 /// </summary> private List<PageNum> GetPageList(int currentPage, int pageCount) { List<PageNum> result = new List<PageNum>(); result.Add(new PageNum(1)); if (currentPage > 4) { result.Add(new PageNum(0, 1)); } for (int i = currentPage - 2; i <= currentPage + 2; i++) { if (i > 1 && i < pageCount) { result.Add(new PageNum(i)); } } if (pageCount - currentPage > 3) { result.Add(new PageNum(0, 1)); } result.Add(new PageNum(pageCount)); return result; } #endregion } }