WebPart中使用Nvelocity模板引擎来进行呈现

本文介绍如何在Office SharePoint 2007的WebPart中使用NVelocity模板引擎,实现界面与数据的分离,并探讨了利用NVelocity进行WebPart换肤的可能性。
NVelocity是一套强大的模板引擎,在我之前的随笔中,有过使用它来呈现页面及生成静态页的例子。
通过使用它,我们可以达到界面与数据的完成分离(当然需要一些设计手段来支持)。
我在公司里的工作主要就是在office sharepoint2007的基础上进行一些类型信息系统的门户站点开发。
而我所在的组开发出了一套通用的组件库,比如类似163新闻的列表新闻部件、FLASH新闻部件等webpart.
目的就在于每建设一个网站时,可以使用这些通用的组件库来进行快速的开发,甚至于我们只需要拖拉+设计css样式就可以完成一个站点的开发。
但是,在不断的开发新网站过程中,发现虽然通过更改css样式可以达到控制webpart的呈现样式。但是,还是有些需求是无法通过更改css来实现的。
当然,这仅仅是对需求的不满足,而我引入模板引擎的另一个想法是:
在指定的目录下,针对每一个webpart都创建它的相应文件夹,在这个文件夹下可以放置多个模板及一个描述模板信息的xml文件。
这样,在页面上使用webpart的时候,我们就可以遍历这个模板文件夹,并读取模板信息,以供选择。
也就是说,我们可以通过这种方式来实现类似webpart换肤的功能(采用模板达到的功能肯定比换肤更强大了)。
如果我们将模板文件夹建到_layouts目录下,甚至还可以达到多个站点共用一套webpart模板。
--------------------------
针对这个设想,我对webpart应用nvelocity进行了简单的测试:
Step1:创建webpart,并在其中输出相关数据<需要引用NVelocity.dll,并using 相关的命名空间>
ContractedBlock.gifExpandedBlockStart.gifCode
  1[Guid("09a3886f-ccb9-44ed-8838-82969522c37b")]
  2    public class NVelocityTestPart : System.Web.UI.WebControls.WebParts.WebPart,ICallbackEventHandler
  3ExpandedBlockStart.gifContractedBlock.gif    {
  4        public NVelocityTestPart()
  5ExpandedSubBlockStart.gifContractedSubBlock.gif        {
  6            this.ExportMode = WebPartExportMode.All;
  7            this.ChromeType = PartChromeType.None;   
  8        }

  9        //可以写个EditorPart,用于从指定的文件夹中循环列出模板文件,让使用者选择
 10        //并且创建一个对应的xml文件,用于给模板添加描述信息等。
 11        private string vmPath = "NvelocityDir";
 12        [
 13        WebBrowsable(true),
 14        WebDescription("模板文件夹路径"),
 15        WebDisplayName("模板文件夹路径"),
 16        Personalizable(true)
 17        ]
 18        public string VmPath
 19ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 20ExpandedSubBlockStart.gifContractedSubBlock.gif            get return vmPath; }
 21ExpandedSubBlockStart.gifContractedSubBlock.gif            set { vmPath = value; }
 22        }

 23        private string OutputAjaxFunction()
 24ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 25            System.Text.StringBuilder sb = new System.Text.StringBuilder();
 26            sb.Append("<script type=\"text/javascript\" language=\"javascript\">");
 27            sb.Append("\r\n function callServer(cName)\r\n {");
 28            sb.Append(this.Page.ClientScript.GetCallbackEventReference(this"cName""callbackHandler""")+";");
 29            sb.Append("\r\n }");
 30            sb.Append("\r\n </script>");
 31            return sb.ToString();
 32        }

 33        public string CallbackHandle()
 34ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 35            System.Text.StringBuilder sb = new System.Text.StringBuilder();
 36            sb.Append("<script type=\"text/javascript\" language=\"javascript\">");
 37            sb.Append("function callbackHandler(rResult)");
 38            sb.Append("{");
 39            sb.Append("document.getElementById('callbackContainer').innerText=rResult;");
 40            sb.Append("}");
 41            sb.Append("</script>");
 42            return sb.ToString();
 43        }

 44        protected override void OnInit(EventArgs e)
 45ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 46            //base.OnInit(e);
 47            this.Page.ClientScript.RegisterStartupScript(this.GetType(), "AjaxFunc", OutputAjaxFunction());
 48        }

 49        protected override void RenderContents(HtmlTextWriter writer)
 50ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 51            base.RenderContents(writer);
 52            if (!System.IO.Directory.Exists(this.Page.Server.MapPath(vmPath)))
 53ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 54                writer.Write("模板文件夹不存在!");
 55                return;
 56            }

 57            try
 58ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 59                Author a = new Author();
 60                a.Name = "xu zhi ze";
 61                a.Age = 24;
 62                Author a1 = new Author();
 63                a1.Name = "McJeremy";
 64                a1.Age = 25;
 65                System.Collections.Generic.List<Author> us = new System.Collections.Generic.List<Author>();
 66                us.Add(a);
 67                us.Add(a1);
 68
 69                VelocityEngine vEngine = new VelocityEngine();
 70                ExtendedProperties props = new ExtendedProperties();
 71                props.AddProperty(RuntimeConstants.RESOURCE_LOADER, "file");
 72                //props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, System.IO.Path.GetDirectoryName(this.Page.Request.PhysicalPath));
 73                props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH,this.Page.Server.MapPath(this.vmPath));
 74                props.AddProperty(RuntimeConstants.INPUT_ENCODING, "gb2312");
 75                props.AddProperty(RuntimeConstants.OUTPUT_ENCODING, "gb2312");
 76                vEngine.Init(props);
 77
 78                Template tmp = vEngine.GetTemplate("default.vm");
 79
 80                IContext vContext = new VelocityContext();
 81                vContext.Put("Version""1.0.0.0");
 82                vContext.Put("Author", a);
 83                vContext.Put("Users", us);
 84                vContext.Put("Instance"this);
 85
 86                System.IO.StringWriter sw = new System.IO.StringWriter();
 87                tmp.Merge(vContext, sw);
 88
 89                writer.Write(sw.ToString());
 90            }

 91            catch (System.Exception ex)
 92ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 93                writer.Write(ex.Message);
 94            }

 95           
 96        }

 97
 98ContractedSubBlock.gifExpandedSubBlockStart.gif        ICallbackEventHandler 成员#region ICallbackEventHandler 成员
 99        string rResult = string.Empty;
100        string ICallbackEventHandler.GetCallbackResult()
101ExpandedSubBlockStart.gifContractedSubBlock.gif        {
102            return rResult;
103        }

104        void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
105ExpandedSubBlockStart.gifContractedSubBlock.gif        {
106            if (string.IsNullOrEmpty(eventArgument))
107                rResult = "调用ajax时,传递的值为空!";
108            else
109                rResult = "调用ajax时,传递的值为:" + eventArgument;
110        }

111        #endregion

112    }
Step2:创建模板文件 default.vm,并写呈现逻辑:
ContractedBlock.gifExpandedBlockStart.gifCode
 1<pre>
 2/******************************** 
 3/* A Test of NVelocity in WebPart  
 4/* www.cnblogs.com/mcjeremy  
 5/******************************** 
 6
 7<h1>This is a test!</h1>
 8Version: ${Version} 
 9Author : ${Author.Name} 
10Age : ${Author.Age} 
11
12
13<h3>NVelocity Test</h3>
14
15Version: $!Version 
16Author : $Author.Name 
17Age : $Author.Age 
18
19#set($company="Mcjeremy'company")
20Copyright By <span style="color:red;"> ${company}</span> 
21
22
23Users Are: 
24#set($userNum=1) 
25#foreach($user in $Users)
26 <div style="margin:0px;padding:0px;border:1px dashed blue;width:200px;font-size:14px;font-weight:bold;">
27  User $userNum 
28  Name:  $user.Name 
29  Age:   $user.Age 
30  #set($userNum=$userNum+1) 
31 </div> 
32#end
33
34<h3>异步测试</h3>
35<!--$Instance -->
36$Instance.CallbackHandle()
37<span style="cursor:pointer;color:red;" onclick="callServer('xu zhi ze')">点击我</span>
38<div id="callbackContainer" style="border:1px dotted silver;width:300px;height:50px;"></div>
39</pre>

Step3:查看的运行效果如下:


很显然,在webpart中使用nvelocity是可行的,而且非常简单。
接下来要做的事就是
1、实现在一个目录下放置多个模板文件,
2、编写xml文件来描述这些模板,
3、编写一个editorpart来读取这个目录下的模板描述xml,并生成模板的列表,以供使用者选择。
---
目前只测试了在webpart中使用nvelocity。没有进行模板选择的测试。
实际上,模板选择的工作难点在于写editorpart时的xml读取和分析(实际上,这也并不难,毕竟是基础知识的运用而已)
有了使用nvelocity的方法,再加上模板选择的功能应该就容易多了。
等有空了再测试模板选择~~~~~
----
如果各位达人有这方面的经验或者更好的方法,希望能指教指教,大家共同进步。

转载于:https://www.cnblogs.com/McJeremy/archive/2009/08/18/1548724.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值