下面這個巨集可以讓你在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
這就是一個可以完全使用相對路徑的方法了,包括子頁面嵌入其他的子頁面,而不會造成使用的困擾。