zoukankan      html  css  js  c++  java
  • WebPart中使用Nvelocity模板引擎来进行呈现

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

    分类: SharePoint
    NVelocity是一套强大的模板引擎,在我之前的随笔中,有过使用它来呈现页面及生成静态页的例子。
    通过使用它,我们可以达到界面与数据的完成分离(当然需要一些设计手段来支持)。
    我在公司里的工作主要就是在office sharepoint2007的基础上进行一些类型信息系统的门户站点开发。
    而我所在的组开发出了一套通用的组件库,比如类似163新闻的列表新闻部件、FLASH新闻部件等webpart.
    目的就在于每建设一个网站时,可以使用这些通用的组件库来进行快速的开发,甚至于我们只需要拖拉+设计css样式就可以完成一个站点的开发。
    但是,在不断的开发新网站过程中,发现虽然通过更改css样式可以达到控制webpart的呈现样式。但是,还是有些需求是无法通过更改css来实现的。
    当然,这仅仅是对需求的不满足,而我引入模板引擎的另一个想法是:
    在指定的目录下,针对每一个webpart都创建它的相应文件夹,在这个文件夹下可以放置多个模板及一个描述模板信息的xml文件。
    这样,在页面上使用webpart的时候,我们就可以遍历这个模板文件夹,并读取模板信息,以供选择。
    也就是说,我们可以通过这种方式来实现类似webpart换肤的功能(采用模板达到的功能肯定比换肤更强大了)。
    如果我们将模板文件夹建到_layouts目录下,甚至还可以达到多个站点共用一套webpart模板。
    --------------------------
    针对这个设想,我对webpart应用nvelocity进行了简单的测试:
    Step1:创建webpart,并在其中输出相关数据<需要引用NVelocity.dll,并using 相关的命名空间>
     
      1  [Guid( " 09a3886f-ccb9-44ed-8838-82969522c37b " )]
      2       public   class  NVelocityTestPart : System.Web.UI.WebControls.WebParts.WebPart,ICallbackEventHandler
      3       {
      4           public  NVelocityTestPart()
      5           {
      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
     19           {
     20               get   {  return  vmPath; } 
     21               set   { vmPath  =  value; } 
     22          } 
     23           private   string  OutputAjaxFunction()
     24           {
     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()
     34           {
     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)
     45           {
     46               // base.OnInit(e); 
     47               this .Page.ClientScript.RegisterStartupScript( this .GetType(),  " AjaxFunc " , OutputAjaxFunction());
     48          } 
     49           protected   override   void  RenderContents(HtmlTextWriter writer)
     50           {
     51               base .RenderContents(writer);
     52               if  ( ! System.IO.Directory.Exists( this .Page.Server.MapPath(vmPath)))
     53               {
     54                  writer.Write( " 模板文件夹不存在! " );
     55                   return ;
     56              } 
     57               try 
     58               {
     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)
     92               {
     93                  writer.Write(ex.Message);
     94              } 
     95             
     96          } 
     97  
                 #region  ICallbackEventHandler 成员 
     99           string  rResult  =   string .Empty;
    100           string  ICallbackEventHandler.GetCallbackResult()
    101           {
    102               return  rResult;
    103          } 
    104           void  ICallbackEventHandler.RaiseCallbackEvent( string  eventArgument)
    105           {
    106               if  ( string .IsNullOrEmpty(eventArgument))
    107                  rResult  =   " 调用ajax时,传递的值为空! " ;
    108               else 
    109                  rResult  =   " 调用ajax时,传递的值为: "   +  eventArgument;
    110          } 
    111           #endregion 

    112      }

    Step2:创建模板文件 default.vm,并写呈现逻辑:

     
     1  < pre > 
     2  /******************************** 
     3  /* A Test of NVelocity in WebPart  
     4  /* www.cnblogs.com/mcjeremy  
     5  /******************************** 
     6  
     7  < h1 > This is a test! </ h1 > 
     8  Version: ${Version} 
     9  Author : ${Author.Name} 
    10  Age : ${Author.Age} 
    11  
    12  
    13  < h3 > NVelocity Test </ h3 > 
    14  
    15  Version: $!Version 
    16  Author : $Author.Name 
    17  Age : $Author.Age 
    18  
    19  #set($company="Mcjeremy'company")
    20  Copyright By  < span  style ="color:red;" >  ${company} </ span >  
    21  
    22  
    23  Users Are: 
    24  #set($userNum=1) 
    25  #foreach($user in $Users)
    26    < div  style ="margin:0px;padding:0px;border:1px dashed blue;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;300px;height:50px;" ></ div > 
    39  </ pre >


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

    很显然,在webpart中使用nvelocity是可行的,而且非常简单。
    接下来要做的事就是
    1、实现在一个目录下放置多个模板文件,
    2、编写xml文件来描述这些模板,
    3、编写一个editorpart来读取这个目录下的模板描述xml,并生成模板的列表,以供使用者选择。
    ---
    目前只测试了在webpart中使用nvelocity。没有进行模板选择的测试。
    实际上,模板选择的工作难点在于写editorpart时的xml读取和分析(实际上,这也并不难,毕竟是基础知识的运用而已)
    有了使用nvelocity的方法,再加上模板选择的功能应该就容易多了。
    原理很简单:在EditorPart中指定WebPart模板所在的文件夹(相对路径),并通过输入的文件夹路径获取该文件夹下的templates.xml(即模板描述文件)。
    然后列出该模板描述文件中的模板列表供选择。模板描述文件格式及内容如下(如果要在项目中应用,可能还需要作相应的更改):

     
     1  <? xml version="1.0" encoding="utf-8" standalone="yes"  ?> 
     2  < TemplateFiles > 
     3     < TemplateFile > 
     4      < FileName > 
     5        <![CDATA[ default.vm ]]> 
     6      </ FileName >  
     7      < TemplateName > 默认 </ TemplateName > 
     8      < Description > 描述111111 </ Description > 
     9      < Author > pcitxzz </ Author > 
    10      < CreateDate > 2009-08-18 </ CreateDate > 
    11     </ TemplateFile > 
    12       < TemplateFile > 
    13      < FileName > <![CDATA[ new2.vm ]]> </ FileName >   <!-- 文件名 --> 
    14      < TemplateName > 新的 </ TemplateName > <!-- 模板名 --> 
    15      < Description > 描述2222 </ Description > <!-- 模板描述 --> 
    16      < Author > pcitxzz </ Author > <!-- 创建者 --> 
    17      < CreateDate > 2009-08-18 </ CreateDate > <!-- 创建日期 --> 
    18     </ TemplateFile > 
    19  </ TemplateFiles >

    在编写EditorPart时,读取这个xml文件并分析即可。
    完成EditorPart的编写后,就可以在webpart中进行应用了。
    ------------------------------------------
    以下是我测试的相关截图:
    No1:EditorPart中选择模板的效果:
     
    No2:使用默认模板时的效果:
     
    No3:使用“新的”模板时的效果:
     

    可以看出,通过这种方式为同一个webpart应用不同的模板十分方便。
    尤其是在实现CSS样式无法实现的布局时或需要一些特殊功能时,您可以考虑这种实现方式。
    ----
    相关源码:/Files/McJeremy/NVelocityTestPart.rar 

  • 相关阅读:
    Install Jetty web server on CentOS 7 / RHEL 7
    Linux MYSQL:dead but pid file exists
    Tomcat7注册为Linux服务
    CentOS查看版本及架构信息
    CentOS(6.8)7 安装 Mysql 5.7
    CentOS7 截图
    Kitematic when login show Error:Tunning socket could not be established
    Installing and removing VNC Connect | Red Hat | VNC Connect
    使用 Nexus Repository Manager 搭建私有docker仓库
    Docker attach
  • 原文地址:https://www.cnblogs.com/ningang/p/4321959.html
Copyright © 2011-2022 走看看