讓Web專案中Velocity的#parse支援相對路徑

weixin_34304013發表於2008-02-05
 

下面這個巨集可以讓你在web專案中使用相對路徑來包含其他的模板檔案

#macro(invoke $page)
    #if($page.startsWith("/"))
        #parse($page)
    #else
        #set($uri = $request.getAttribute("javax.servlet.include.request_uri"))
        #if(!$uri)#set($uri = $request.getServletPath())#end
        #set($path = $uri.substring(0, $uri.lastIndexOf("/")))
        #parse("$path/$page")
    #end
#end

把這段程式碼加在VM_global_library.vm中,你就可以在頁面模板中用#invoke("head.vm")來在頁面中嵌入其他的模板檔案,比起用#parse指定絕對路徑省事很多。

不過這種做法有一個缺點:當子頁面還欠有其他頁面的時候,相對路徑就有點問題,是相對於主頁面而非當前頁面,這也會給使用上造成一些困擾,但解決的辦法還是有的,相對比較複雜而已。

首先我們需要編寫一個Toolbox類,例如MyVelocityTool,該類實現介面ViewTool,程式碼如下:

public class MyVelocityTool implements ViewTool {

 protected HttpServletRequest request;
 protected HttpServletResponse response;
 protected ServletContext context;
 protected VelocityContext velocity;

 /*
  * Initialize toolbox
  * @see org.apache.velocity.tools.view.tools.ViewTool#init(java.lang.Object)
  */
 public void init(Object arg0) {
  if(arg0 instanceof ViewContext){
   ViewContext viewContext = (ViewContext) arg0;
   request = viewContext.getRequest();
   response = viewContext.getResponse();
   context = viewContext.getServletContext();
   velocity = (VelocityContext)viewContext.getVelocityContext();
  }
  else if(arg0 instanceof ServletContext){
   context = (ServletContext)arg0;
  }
 }

 public String current_template(){
  return velocity.getCurrentTemplateName();
 }
}

接著在velocity-toolbox.xml中定義這個Toolbox類

 
     dlog
     request
     com.liusoft.dlog4j.DLOG_VelocityTool
 

最後修改#invoke巨集如下:

#macro(invoke $page)
    #if($page.startsWith("/"))
        #parse($page)
    #else
        #set($uri = $dlog.current_template())
        #set($path = $uri.substring(0, $uri.lastIndexOf("/")))
        #parse("$path/$page")
    #end
#end

這就是一個可以完全使用相對路徑的方法了,包括子頁面嵌入其他的子頁面,而不會造成使用的困擾。

相關文章