随笔 - 196  文章 - 43  评论 - 4286 

    作为产品中的一大特色,模板机制一经推出,就引来了大家特别是站长们的关注。但它所饱受的风风
雨雨也成了那时不少人关注的话题。而今天本人将结合在产品组中的开发经历,介绍一下模板机制在设计
使用时的一些体会心得。希望借此陋文,使模板机制揭开“神秘”面纱,为大家在实际设计中提供一些有
价值的参考和建议。

    好了,开始今天的话题:)

    首先阐述一下模板设计的目标,因为这对于它最终要实现的功能非常重要。考虑到国内大部分站长基
本上都不具备.net开发背景,而我们的模板就是要降低这个门槛,便于站长进行设计订制以及修改等。而
另一个目的就是要提升aspx页面的访问速度,所以我们并未在模板设计时引入(web)控件机制,因为如果
使用.net控件,在windows的临时目录中会进行控件的订制生成(按用户设置的属性)。虽然在.net2.0
使用了fastobjectfactory的机制来提升页面生成的效率,比如使用batch批量编译选项 (web.config
文件中配置)生成的DLL(这里的DLL也是在临时目录下生成的随机命名的DLL文件,且重复编译的情况在所
难免)。但最终还是无法改变要生成服务器端控件的过程。
  
    我们在设计模板本身所提供的语法时,尽可能逼近HTML的书写习惯,这样只要有HTML编写网页经验的
人就会很容易适应这种书写方式。当然有 asp开发经验的站长也能很快上手,因为模板的语法非常类似于
asp, 比如有<%if ...%>,<%else%>这样的写法等等。另外我们的模板语法也力求简练精悍,只需很少的
语法规则就直接支持生成内容丰富且形式多样的页面。说了这些,相信大家已经有兴趣来一看究竟了。不忙,
这里先要介绍一下如何使用模板机制来生成aspx页面。因为我有一位从事.net开发多年的朋友,在一次聊
天时他说,修改我们的前台页面时要手工修改"aspx/.../"下的相应的aspx文件,而当他看到 aspx文件中
的内容时大吃一惊,举个例子如下(aspx/1/logout.aspx):

.....命名空间和类的引用

 1<script runat="server">
 2override protected void OnInit(EventArgs e)
 3{
 4
 5 base.OnInit(e);
 6
 7 templateBuilder.Append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN
 8   \" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n");
 9 templateBuilder.Append("<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n");
10 templateBuilder.Append("<head>\r\n");
11 templateBuilder.Append("<meta http-equiv=\"Content-Type\" content=\"text/html; 
12   charset=utf-8\" />\r\n");
13 templateBuilder.Append("" + meta.ToString() + "\r\n");
14 templateBuilder.Append("<title>" + pagetitle.ToString() + " " + 
15   config.Seotitle.ToString().Trim() + " - " + 
16   config.Forumtitle.ToString().Trim() + " - Powered by Discuz!NT
17   </title>\r\n");
18 templateBuilder.Append("<link rel=\"icon\" href=\"favicon.ico\" 
19   type=\"image/x-icon\" />\r\n");
20 templateBuilder.Append("<link rel=\"shortcut icon\" href=\"favicon.ico\" 
21   type=\"image/x-icon\" />\r\n");
22 templateBuilder.Append("<!-- 调用样式表 -->\r\n");
23 templateBuilder.Append("<link rel=\"stylesheet\" href=\"templates/" + 
24   templatepath.ToString() + "/dnt.css\" 
25   type=\"text/css\" media=\"all\"  />\r\n");
26 templateBuilder.Append("" + link.ToString() + "\r\n");
27 templateBuilder.Append("<script type=\"text/javascript\" src=\"templates/" + 
28   templatepath.ToString() + "/report.js\"></" + "script>\r\n");
29 templateBuilder.Append("<script type=\"text/javascript\" src=\"templates/" + 
30   templatepath.ToString() + "/common.js\"></" + "script>\r\n");
31 templateBuilder.Append("<script type=\"text/javascript\" src=\"editor/common.js\">
32   </" + "script>\r\n");
33 templateBuilder.Append("<script type=\"text/javascript\" src=\"editor/menu.js\">
34   </" + "script>\r\n");
35 templateBuilder.Append("" + script.ToString() + "\r\n");
36 templateBuilder.Append("</head>\r\n");
37
38
39

    相信大家看到这样的aspx页面都会晕上一阵子,直接修改的想法已变得非常不现实了,简直是“不
可能完成的任务”。而实际上,我们并不希望大家或站长来完成这项工作。因为这是系统自动生成的。
而生成的前提就是在template/下的模板“目录”中的HTM文件。还是借用上面的logout,只是这里要看
的是模板目录下同名的logout.htm模板文件。它的内容如下:

 

 1<%template _header%>
 2<div id="foruminfo">
 3<div class="userinfo">
 4   <h2><a href="{config.forumurl}">{config.forumtitle}</a> <strong>用户退出</strong></h2>
 5</div>
 6</div>
 7<!--TheCurrent end-->
 8<%template _msgbox%>
 9</div>
10<%template _footer%>
11

 
    大家可能会说,难道就是这几行就实现了上面aspx页面的内容吗?当然不是了,请大家注意:

     

1<%template _header%>
2

    这一行,其实就是告诉模板页面生成器: 这是一个子模板。

    因为我们在开始设计模板机制时就想到要简化模板代码并提升可重用性,因此要支持子模板机制。
这就类似于设计网页时的页首和页尾,我们在网页引用时,只需要include进来即可,而当修改页首和
页尾时,只须变动相应文件即可。

    这里不妨再打开_header.htm(注意子模板名称要用下划线开头),发现内容如下:

1<%template _pageheader%>
2<body>
3<div id="append_parent"></div>
4<div id="container">
5<!--header start-->
6<div id="header">
7     .
8
9

    有意思,又是一个“子模板”出现在了第一行。不错,我们的机制允许模板被嵌套使用,这样会
使页面的“组装”更加灵活多样。

    即然都走到这一步,不妨再打开_pageheader子模板,正所谓“不撞南墙不回头”嘛:)

 1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR
 2/xhtml1/DTD/xhtml1-transitional.dtd">
 3<html xmlns="http://www.w3.org/1999/xhtml">
 4<head>
 5<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 6{meta}
 7<title>{pagetitle} {config.seotitle} - {config.forumtitle} - Powered by Discuz!NT</title>
 8<link rel="icon" href="favicon.ico" type="image/x-icon" />
 9<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
10<!-- 调用样式表 -->
11<link rel="stylesheet" href="templates/{templatepath}/dnt.css" type="text/css" media="all"/>
12{link}
13<script type="text/javascript" src="templates/{templatepath}/report.js"></script>
14<script type="text/javascript" src="templates/{templatepath}/common.js"></script>
15<script type="text/javascript" src="editor/common.js"></script>
16<script type="text/javascript" src="editor/menu.js"></script>
17{script}
18</head>
19
20

    折腾了一圈,到这里出现了上面aspx页中的对应内容,有意思吧,不过里面的{pagetitle}和{
config.seotitle}以及{config.forumtitle}这样的东东又是什么呢? 其实非常简单,这就是按照模
板语法格式所书写的代码,因为这两处在模板生成之后会变成

   

1     templateBuilder.Append("<title>" + pagetitle.ToString() + " " + 
2   config.Seotitle.ToString().Trim() + " - " + 
3   config.Forumtitle.ToString().Trim() + " - Powered by Discuz!NT
4   </title>\r\n");

 

    好了,到了这里我们应该清楚了,以后要修改前台页面的一个标准流程:

    1.按模板语法修改相应的模板文件夹下的模板文件;
    2.在后台生成或使用官方的模板生成器生成相应aspx页面即可;
   
    其实流程非常简单,相信即使不懂aspx开发的朋友也会很快适应并上手。前提就是要了解模板语
法,除了上面所说的以外,还有一些常用的语法如下图:

       
    这里不妨引用官方文档中的链接,里面的说明会更清楚:)

    相关链接如下:http://nt.discuz.net/download/doc/dnt_2_skindoc.zip

 

    好了,目前我们只是知道了如使使用和修改它,但所谓的“模板生成”机制又是个什么样子呢!
必定到这里我们只走完了一半旅途,下面将会介绍模板的生成机制。


    首先要看一下后台的模板(列表)管理界面,如下图:

 

    从上图可知道,模板是按名称(目录)来进行管理的,而每个模板都有名称,存放路径,版权,
作者等相关信息。而这此信息都是来自于每个模板(目录)下的about.xml文件,这里将它的内容贴
出来:

 1<?xml version="1.0" encoding="utf-8" ?> 
 2<about>
 3     <template name="basic"
 4          author="Discuz!NT"
 5          createdate = "2007-11-12"
 6          ver="1.1112"
 7          fordntver="2.0"
 8          copyright="Copyright 2007 Comsenz Inc." />
 9</about>
10
11

    注: 上图中的那个“乐队演出”图片其实是模板目录下的about.png文件,它相当于一张预览图。

    需要说明的是上图中不是所有模板都能在前台使用,而是当被标记为“已入库”才可在前台使用,
而入库即数据库,下面就是数据库中的截图:

     
    
    而接下来要说的,就是模板列表中每个模板后面的“生成”链接所要干的活了。

    如果大家手头上有reflector的话,请使用这个工具加载我们官方提供的产品目录下的bin文件夹
中的discuz.common.dll文件,找到 PageTemplate这个类。这里为了便于说明,将反射所得到的代码
加上注释贴出来:

 

Code


    基本上都是对正则式的使用,因为本人不是这方面的高手,所以就不多说了,相信开源之后大家拿
源码和注释一看便知:)

    这里需要说明的就是ReplaceSpecialTemplate(string forumpath,string skinName,....) 这个函
数,它的实现我们要到discuz.forum.dll中去找,这里为了方便,直接就将反射出来的代码加上注释贴
出来,大家一看便知:

 

 1public class ForumPageTemplate : PageTemplate
 2{
 3
 4 /// <summary>
 5 /// 解析特殊变量
 6 /// </summary>
 7 /// <param name="skinName">皮肤名</param>
 8 /// <param name="strTemplate">模板内容</param>
 9 /// <returns></returns>

10 public override string ReplaceSpecialTemplate(string forumpath,string skinName,string strTemplate)
11 {
12  Regex r;
13  Match m;
14  
15  StringBuilder sb = new StringBuilder();
16  sb.Append(strTemplate);
17      r = new Regex(@"({([^\[\]/\{\}='\s]+)})", RegexOptions.IgnoreCase|RegexOptions.Multiline|RegexOptions.Compiled);
18  for (m = r.Match(strTemplate); m.Success; m = m.NextMatch()) 
19  {
20   if (m.Groups[0].ToString() == "{forumversion}")
21   {
22    sb = sb.Replace(m.Groups[0].ToString(), Utils.GetAssemblyVersion());
23   }

24   else if (m.Groups[0].ToString() == "{forumproductname}")
25   {
26    sb = sb.Replace(m.Groups[0].ToString(), Utils.GetAssemblyProductName());
27   }

28  }

29
30  foreach(DataRow dr in GetTemplateVarList(forumpath,skinName).Rows)
31  {
32   sb = sb.Replace(dr["variablename"].ToString().Trim(), dr["variablevalue"].ToString().Trim());
33  }

34  return sb.ToString();
35 }

36
37
38 /// <summary>
39 /// 获取模板内容
40 /// </summary>
41 /// <param name="skinName">皮肤名</param>
42 /// <param name="templateName">模板名</param>
43 /// <param name="nest">嵌套次数</param>
44 /// <param name="templateid">皮肤id</param>
45 /// <returns></returns>

46 public override string GetTemplate(string forumpath,string skinName, string templateName, int nest,int templateid)
47 {
48  return base.GetTemplate(forumpath,skinName,templateName,nest,templateid);
49 }

50
51 /// <summary>
52 /// 获得模板变量列表
53 /// </summary>
54 /// <param name="skinName">皮肤名</param>
55 /// <returns></returns>

56 public static DataTable GetTemplateVarList(string forumpath,string skinName)
57 {
58  Discuz.Cache.DNTCache cache = Discuz.Cache.DNTCache.GetCacheService();
59                DataTable dt = cache.RetrieveSingleObject("/Forum/" + skinName + "/TemplateVariable"as DataTable;
60
61  if(dt != null)
62  {
63   return dt;
64  }

65  else
66  {
67   DataSet dsSrc = new DataSet("template");
68   string[] filename = new string[1{Utils.GetMapPath(forumpath + "templates/" + skinName + "/templatevariable.xml")};
69    
70   if (Utils.FileExists(filename[0]))
71   {
72         dsSrc.ReadXml(filename[0]);
73
74                              if (dsSrc.Tables.Count == 0)
75                              {
76                                 
77                              }

78   }

79   else
80   {
81       
82   }

83
84                        cache.AddSingleObject("/Forum/" + skinName + "/TemplateVariable", dsSrc.Tables[0], filename);
85   return dsSrc.Tables[0];
86  }

87 }
 
88}

89
90


    相信看到这里,熟悉设计模式的朋友会看出来,这里用到了"Template Method"模式,因为这
种模式很简单,就不多做介绍了,相关信息可以看一下GOF的那本书或到网上一搜便知。

    下面要说的就是上面的这个 ForumPageTemplate类目前所要实现的功能。因为模板中要被订制
的东西有很多,而我们目前所搭建的功能只是为了生成和转换时使用,当用户有要替换的特殊变量
就会出现无法订制的情况。所以才提供了这个类以便实现与模板有关的用户订制需求。当然目录所
提供的功能只是简单的替换而已,但并不排除以后随着用户口味的挑剔而进行升级扩展的可能。

    而用户进行特殊变量定制也非常简单,只要在上面所贴的后台“模板列表”图中的后面点击相
应的“管理”链接之后就会看到下面的页面,如图:


    
    只要再点击右下方的“模板变量列表”,即可以进入定制模板变量的页面,如图:

    
    大家只要进行相应操作设置即可。


    好了,关于模板机制的介绍,这里就先告一段落了。有问题的朋友可以在回复中进行交流和发
EMAIL给我(daizhj617595@126.com,daizhj@gmail.com,daizhj@discuz.com)。

    关键字:discuz,discuz!nt,设计模式,template,template mothod,daizhj,代震军
   

 

posted on 2007-12-17 18:32 代震军 阅读(8652) 评论(53)  编辑 收藏 网摘 所属分类: 设计模式其它Discuz!NT

  回复  引用  查看    
2007-12-17 19:29 | 暗香浮动      
有趣,刚好在看控件的itemplaet机制。
  回复  引用  查看    
2007-12-17 21:13 | kwklover      
机制是不错,不过感觉用正则表达样实现不够优雅。
  回复  引用    
2007-12-17 22:10 | cw[未注册用户]
写得不错, 支持一下.

有些不明白, 为什么不用NVelocity作为模板的实现机制?
还有采用控件的速度, 是不是就是一定赶不上采用模板的机制呢?
还有采用正则式是不是有些乱或是效率上不够高呢?

谢谢指教.

  回复  引用  查看    
2007-12-18 08:50 | 猪怕壮      
学习了,谢谢
  回复  引用  查看    
2007-12-18 08:52 | zhouyou96      
哈,好文
  回复  引用  查看    
2007-12-18 08:53 | Dove.Net      
在这提一个问题,一下不明白DNT的数据库设计为什么许多字段都使用nchar而不是nvarchar?如dnt_topics表的title nchar(60),dnt_users表的username nchar(20)等等?
  回复  引用  查看    
2007-12-18 08:56 | 戏水      
cw : 这里采用正则是进行模板生成aspx,而不是每次访问都用正则解析。
生成时效率稍低没有关系。一劳永逸的事情。

  回复  引用  查看    
2007-12-18 08:58 | 戏水      
NVelocity 虽然强大 。但毕竟是人家的东西。
而且也还没有十分稳定 。

  回复  引用  查看    
2007-12-18 09:56 | 书生多命贱      
nchar类型的字段,性能比nvarchar要好,不管是建索引,还是查询,性能都要好的多!但是他每个内容的长度都是固定的,不足的会自动补空格!可能会占空间一点!
  回复  引用    
2007-12-18 09:58 | huobazi[未注册用户]
title nchar(60),username nchar(20)??
  回复  引用    
2007-12-18 10:01 | oldmoon[未注册用户]
机制是不错,但是对于很长站长,也要学习老长时间
  回复  引用  查看    
2007-12-18 18:19 | daizhj      
@kwklover
这里主要是生成时进行,且不存在效率上的问题,当然在iis上的生成效率还是关注的焦点

  回复  引用  查看    
2007-12-18 18:19 | daizhj      
@oldmoon
其实模板语法相比C#或VB要少很多了,相信很快就会上手的:)

  回复  引用  查看    
2007-12-18 18:21 | daizhj      
@猪怕壮
呵呵:)

  回复  引用  查看    
2007-12-18 18:22 | daizhj      
@zhouyou96
过奖了:)

  回复  引用  查看    
2007-12-18 18:31 | daizhj      
@暗香浮动
有什么心得不妨交流一下,呵呵:)

  回复  引用    
2007-12-19 11:23 | gzj[未注册用户]
--引用--------------------------------------------------
daizhj: @oldmoon
其实模板语法相比C#或VB要少很多了,相信很快就会上手的:)
--------------------------------------------------------
其实模板语法直接使用asp的语法更好。

  回复  引用  查看    
2007-12-19 12:59 | daizhj      
@gzj
模板其实用起来较ASP还要容易一些,因为由前我也开发过ASP,上手这个模板的语法时,一点也不费劲.
如果用户有asp开发经验的话,上手相信也会和我差不多。
但如果仅是HTML书写经验的话,再去学习ASP语法就有些不现实了(因为aspx是asp的接班人嘛)。所以模板语法简单精练才是我们的出发点:)
同时感谢您对我们产品的关注和支持:)

  回复  引用    
2007-12-19 16:50 | 生命过客[未注册用户]
对于模版上的功能,能不能自定义?

最近遇到你们的产品discuz上关于模版上添加功能的问题,头都大了。
我的QQ:113624
有好些问题想请教。谢谢!

  回复  引用  查看    
2007-12-19 19:00 | daizhj      
@生命过客
关于新功能的添加其实不难,主要是aspx.CS页面和.htm的功能添加要相呼应。当然最终的解释还要看官方的。
同时感谢您对我们产品的支持和关注:)

  回复  引用    
2007-12-20 10:28 | 生命过客[未注册用户]
关于新功能的添加其实不难,主要是aspx.CS页面和.htm的功能添加要相呼应。


开始我也是这么想的,aspx.cs代码是指默认模版下的.cs文件吗?
我已经这样做过了,但没有成功,根本没有读取到.我想应该是我哪方面搞错了.
请问一下,htm模版页面的函数是从哪里读过来的?

  回复  引用    
2007-12-20 10:30 | 生命过客[未注册用户]
我没有搞过asp.一开始接触的就是.net,看起来好吃力...
  回复  引用  查看    
2007-12-20 11:10 | daizhj      
@生命过客
没学过asp也没关系,我们的模板语法很简单的。只要写上一小段时间就会适应的:)

另外就是htm中的函数,里面的所有函数都是要被"正则替换"才能变成aspx页的,目前只有几种函数是支持的“datetostr”,“strtoint”,“getsubstring”等,这些都该在官方给的DOC文档中有说明。
您只要按这种写法书写HTM并生成相应模板即可。

另外就是在aspx.cs中要提供新功能的代码,要相对应。比如当在htm中加一个{title},则在aspx.cs页中要有一个public的声明title相对应(一定要在开头声明public)。


  回复  引用    
2007-12-20 15:04 | 生命过客[未注册用户]
您所指的.cs文件是asp/1下的cs文件吗?
  回复  引用  查看    
2007-12-20 15:37 | daizhj      
@生命过客
是的,只有一份

  回复  引用  查看    
2007-12-21 15:11 | ToBin      
这个很值得研究。
希望能出点更多有关discuznt2.0的分析
我想到这来看BLOG的人都是想扩展或者整合dnt的人。
辛苦了。

  回复  引用  查看    
2007-12-21 15:45 | 幕后      
谢谢楼主·收藏下·有时间看看··
  回复  引用  查看    
2007-12-21 17:12 | 代震军      
@幕后
呵呵:)

  回复  引用  查看    
2007-12-21 17:15 | 代震军      
@ToBin
谢谢您对我们产品的关注和支持!
我会在以后侧重聊一下关于整合和扩展的话题的.
只要大家认可,我麻烦一点倒没什么关系,呵呵:)

  回复  引用    
2008-01-14 19:26 | Everett[未注册用户]
@cw
这东西的效率可以忽略吧, 模板一般就生成一次

  回复  引用    
2008-01-23 09:35 | jackdrawjj[未注册用户]
对于discuz的模板机制从效应上来说是不错的,只少比.net控件,不过有一点没有弄明白,即然考虑速度问题,为什么不把头尾文件单独拿出来进行整个文件夹的渲染,并在启动的时候拉开加载至缓存里面再结合url重写进行处理,不是更快吗?
  回复  引用  查看    
2008-01-23 16:46 | 代震军      
@jackdrawjj
首先感谢您的回复以及对我们产品的支持和关注:)
因为每个模版的首和尾有可以有不同,比较我们就有采用FRAME方式的模版,而如果采用您所说的方案的话,就要为每个模版出一个缓存设置(因为我们的产品中
已可以实现不同版块不同模版了)如果模版少还行,多了的话就有些说不过去了,并且首尾文件本身没有太多cs代码调用,所以在程序执行效率和速度上没有太
大差异.
不知道我这样解释您是否明白,如果有问题请跟帖:)

  回复  引用    
2008-05-17 20:50 | 白云1[未注册用户]
生成的aspx页面为什么直接运行,看到的就是没CSS,只有部分内容的页面? 谢谢!
  回复  引用  查看    
2008-05-19 09:28 | 代震军      
@白云1
因为我们的产品使用了URLREWRITE.所以正常运行时,请求的页面(比如说)是
showtopic.aspx ,而最终可被重定向到aspx/1/showtopic.aspx,与相应的CSS文件是在template/default或其它并行的文件夹下的:)

  回复  引用    
2008-06-02 17:04 | 蜗牛2008[未注册用户]
请问楼主,你们开发的时候怎么测试啊?
  回复  引用  查看    
2008-06-03 09:09 | 代震军      
@蜗牛2008
简单的功能只是自己测一下之后,写个功能的使用文档就交给技术支持去测了.复杂的功能就要单元测试一下了(时间允许的情况下).

  回复  引用  查看    
2008-07-02 17:40 | 咖啡猪      
我看到首页index.aspx里面就一句:<%@ Page %>
而且也没有相应的index.aspx.cs文件,我真是一头雾水,iis在接收到index.aspx页面的请求后怎么解释的啊?

  回复  引用  查看    
2008-07-03 09:56 | 代震军      
@咖啡猪
请参见我写的这篇文章,相信能解决您的疑问:
http://www.cnblogs.com/daizhj/archive/2008/01/14/1034103.html" target="_new">http://www.cnblogs.com/daizhj/archive/2008/01/14/1034103.html

模板中的变量怎么产生啊
  回复  引用  查看    
2008-07-31 13:05 | 代震军      
@模板中的变量怎么产生啊
可在相应的cs文件中进行定义,在模版中进行显示操作
当然也可以在模版中声明定义新的变量,可参见我们的模板语法文档:)

  回复  引用  查看    
2008-08-14 10:38 | 飄lá┽蕩去      
楼主可以分析一下DNT的模板和CS的Theme的优缺点吗?没选择CS的架构的一些考虑可以了解下吗?
  回复  引用    
2008-09-19 18:33 | jock[未注册用户]
添加模板变量有什么用?
  回复  引用  查看    
2008-10-11 18:54 | rym1020      
为什么一定要生成aspx呢?直接用httphandler+stringtemplate或nVelocity 不是更简洁吗?
  回复  引用  查看    
2008-12-17 13:19 | Bryan Chow      
@Dove.Net
定长表在查询时有优势

  回复  引用  查看    
2008-12-17 13:21 | Bryan Chow      
@rym1020
生成出来的aspx在运行时二次编译,运行效率绝对要高过其他模板机制

  回复  引用  查看    
2008-12-18 17:11 | John Zhuang      
一直觉得DISCUZ模板机制还不错
在我的新项目“用户空间模块”功能里,该机制已采用
不用自己去整理。在此谢谢了。

  回复  引用    
2009-02-08 19:42 | lulisheng[未注册用户]
为什么页面使用stringbuilder拼不出来一个oninit方法,为什么不在页面上使用<%= %> 这样,和你这种方式不是一样的吗,为什么还要这样呢,请尽快回复我,谢谢,写email也可以lulisheng_007@sohu.com,
  回复  引用  查看    
2009-02-09 09:38 | 代震军      
@lulisheng
主要是使用了模版机制生成的(包括那个oninit方法),而这样做主要是两个原因:
1.站长只要掌握模版语法就可以写页面程序了(不用学习C#)
2.使用stringbuilder,而不是<%= %>这种格式是因为执行效率的原因,前者在页面输出时速度会好一些。

  回复  引用    
2009-04-04 19:00 | weisheng.lu[未注册用户]
楼主我想问一下,如果单独拿 discuz.NT 的模版机制出来,结合在自己项目中,该怎么做呢? 是不是先要制作网站的模版,比如,我写了个 login.html 模版,是不是要先写 login.aspx 对应的 .cs 页面,然后通过模版生成,写入 login.aspx 页面,最近通过 url 重写,我这样说对不对 ?
  回复  引用  查看    
2009-04-07 08:51 | 代震军      
@weisheng.lu
是这样的

  回复  引用  查看    
2009-06-03 12:34 | 杨鑫奇      
在此时间段内不允许访问本论坛


当前服务器时间: 2009-06-03 12:27:44
当前页面 forumindex.aspx
可选择操作: 退出

这个是怎么回事啊。。

nt.discuz.net 是怎么了?

  回复  引用  查看    
2009-06-03 12:45 | 代震军      
@杨鑫奇
应该是后台设置了访问时间段了,只要在管理后台中找到该项设置修改即可。

  回复  引用  查看    
2009-06-07 02:18 | Lowdens      
请问下 为什么修改了aspx/1下的CS文件 为什么没起作用?
如:我修改register.aspx.cs 经调试 完全没有接收到register.aspx文本框的值。




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1003150




相关文章:

相关链接: