2016-02-02 56 views
4

我正在將一組grails 2.0.4應用程序遷移到3.x版本。所有這些都與許多Java應用程序一起部署在同一臺服務器上。使用sitemesh和freemarker模板,這兩套java和grails應用程序都具有共同的外觀和感覺。 但是,使用grails 3.x我無法使通常裝飾工作,應用程序堅持使用layouts/main.gsp來渲染我的gsp。在Grails中使用Sitemesh 3

到目前爲止(grails 2.0.4)提供一個共同的裝飾是相當直接的;每個grails應用程序的文件/WEB-INF/decorators.xml都提供了對可用的自由標記模板的引用。和web.xml中包括SiteMesh的過濾器和freemarker的裝飾的servlet聲明和映射

decorators.xml:從web.xml中

<?xml version="1.0" encoding="UTF-8"?> 
<decorators defaultdir="/"> 
    <excludes> 
     <pattern>/ND/*</pattern> 
     <pattern>/*/ND/*</pattern> 
    </excludes> 
    <decorator name="freemarker" page="myftl.ftl"> 
     <pattern>/*</pattern> 
    </decorator> 
</decorators> 

SiteMesh的過濾器和freemarker的servlet的:

<filter> 
    <filter-name>sitemesh</filter-name> 
    <filter-class>org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>sitemesh</filter-name> 
    <url-pattern>/*</url-pattern> 
    <dispatcher>REQUEST</dispatcher> 
    <dispatcher>ERROR</dispatcher> 
</filter-mapping> 
<servlet> 
    <servlet-name>sitemesh-freemarker</servlet-name> 
    <servlet-class>com.opensymphony.module.sitemesh.freemarker.FreemarkerDecoratorServlet</servlet-class> 
    <init-param> 
     <param-name>TemplatePath</param-name> 
     <param-value>class://</param-value> 
    </init-param>  
    <init-param> 
     <param-name>default_encoding</param-name> 
     <param-value>UTF-8</param-value> 
    </init-param>   
    <load-on-startup>2</load-on-startup> 
</servlet> 
<servlet-mapping> 
    <servlet-name>sitemesh-freemarker</servlet-name> 
    <url-pattern>*.ftl</url-pattern> 
</servlet-mapping> 

什麼我試過了:

  • 我把src/main/webapp/WEB-INF下的decorators.xml
  • 在grails 3.x sitemesh過濾器不存在了,所以我刪除了sitemesh.xml
  • web.xml沒有被使用,所以現在我已經定義了spring/resources.groovy的freemarker servlet:

resources.groovy:

beans = { 
    sitemeshFreemarkerServlet(ServletRegistrationBean) { 
     servlet = bean(FreemarkerDecoratorServlet) 
     urlMappings = ["*.ftl"] 
     loadOnStartup = 2 
    } 
} 

然而,Grails的3.x應用程序 - 堅持使用佈局/ main.gsp來呈現我的GSP頁面。看來decorator.xml沒有被處理。我錯過了什麼?

回答

2

也許是一個醜陋的黑客攻擊,但你可以疊加您的sitemesh處理Grails的一個:

  • 註冊在應用類(或彈簧/資源定製的sitemesh過濾器。常規):
 

    @Bean 
    FilterRegistrationBean sitemeshFilterRegistrationBean() { 
     FilterRegistrationBean reg=new FilterRegistrationBean() 
     reg.setFilter(new MySitemeshFilter()); 
     reg.setInitParameters(["configFile":"WEB-INF/my.sitemesh.xml"]) 
     reg.setUrlPatterns(["/*"]) 
     reg.setDispatcherTypes(DispatcherType.REQUEST,DispatcherType.ERROR); 
     reg.setOrder(0); 
     return reg; 
    } 
 
  • SiteMesh的配置一定不能是默認的,原因Grails的繼續 看完
  • 註冊freemarker的servlet來proccess FTL的:
 

    @Bean 
    ServletRegistrationBean freeMarkerServletRegistrationBean(){ 
     ServletRegistrationBean reg=new ServletRegistrationBean(new 
      FreemarkerDecoratorServlet(),"*.ftl"); 
     reg.addInitParameter("TemplatePath", "class://"); 
     reg.addInitParameter("default_encoding", "UTF-8"); 
     // etc 
     return reg; 
    } 
 
  • 添加定製的sitemesh過濾:
 

import com.opensymphony.module.sitemesh.Config; 
import com.opensymphony.module.sitemesh.Factory 
import com.opensymphony.module.sitemesh.factory.DefaultFactory; 
import com.opensymphony.sitemesh.ContentProcessor; 
import com.opensymphony.sitemesh.DecoratorSelector; 
import com.opensymphony.sitemesh.compatability.DecoratorMapper2DecoratorSelector; 
import com.opensymphony.sitemesh.webapp.SiteMeshWebAppContext; 

import grails.util.Holders; 
import javax.servlet.FilterConfig 

class MySitemeshFilter extends com.opensymphony.sitemesh.webapp.SiteMeshFilter { 

    private static final String MY_SITEMESH_FACTORY = "my.sitemesh.factory"; 
    private FilterConfig filterConfig; 
    @Override 
    public void init(FilterConfig filterConfig) { 
     super.init(filterConfig); 
     filterConfig.getServletContext().setAttribute("grailsApplication", Holders.grailsApplication); 
     this.filterConfig=filterConfig; 
    } 

    protected Factory getFactory(FilterConfig filterConfig) { 
     Config config=new Config(filterConfig) 
     Factory f=(Factory)config.getServletContext().getAttribute(MY_SITEMESH_FACTORY); 
     if (f==null) { 
      f=new DefaultFactory(config); 
      config.getServletContext().setAttribute(MY_SITEMESH_FACTORY, f); 
     } 
     return f; 
    } 

    @Override 
    protected DecoratorSelector initDecoratorSelector(SiteMeshWebAppContext webAppContext) { 
     Factory factory = getFactory(filterConfig); 
     factory.refresh(); 
     return new DecoratorMapper2DecoratorSelector(factory.getDecoratorMapper()); 
    } 
} 
 
  • 在這個過濾器,你必須覆蓋一個新的sitemesh工廠的裝飾選擇,導致默認的是單(原文如此)和Grails已經註冊但其內部GSP proccesing
  • 不應該覆蓋內容proccesor(initContentProcessor法),讓如果你想獲得更多的功能(如exclu Grails的proccess GSP使用默認的sitemesh工廠
  • 的DED模式),你需要重寫整個doFilter方法使用新contentProcessor在contentProcessor.handles(webAppContext)
  • 添加您my.sitemesh.xml和decorators.xml中的src /主/ web應用/ WEB-INF
  • 我添加grailsApplication以在Servlet過濾器的初始化上下文,這樣你可以在FTL模板
  • 使用它,如果你想跳過一些佈局,通過環境內部的Grails佈局
+0

添加條件也許不是最好的解決方案,但它的工作原理!非常感謝! –

相關問題