2016-02-02 4 views
4

Я переношу набор приложений grails 2.0.4 в версию 3.x. Все они развернуты на одном сервере вместе с несколькими java-приложениями. Оба набора приложений java и grails имеют общий внешний вид с использованием шаблонов sitemesh и freemarker. Но с grails 3.x Я не могу сделать работу commond украшением, приложение настаивает на использовании layouts/main.gsp, чтобы отобразить мой gsp вместо этого.Использование Sitemesh в Grails 3

До сих пор (grails 2.0.4), обеспечивающий общее украшение, довольно прям; файл /WEB-INF/decorators.xml каждого приложения grails содержит ссылки на соответствующие шаблоны freemarker. И web.xml включает SiteMesh фильтр и объявление сервлет FreeMarker декоратора и отображение

decorators.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 сервлета из web.xml:

<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> 

Что Я пробовал:

  • Я переместил decorators.xml под src/main/webapp/WEB-INF
  • В grails 3.x фильтра sitemesh больше нет, и поэтому я удалил sitemesh.xml
  • web.xml не используется, поэтому теперь я определил сервлет freemarker в spring/resources.groovy:

resources.groovy:

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

Однако приложения Grails 3.x настаивает на использовании макетов/main.gsp, чтобы сделать мои GSP страницы. Похоже, что decorators.xml не обрабатывается. Что мне не хватает?

ответ

2

Может быть, это некрасив хак, но вы могли бы совместив вашу обработку SiteMesh в Grails одно:

  • Регистрация настраиваемого фильтр SiteMesh в классе Application (или пружинных/ресурсах.заводной):
 

    @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 сервлет 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
  • Переработка
  • вы не должны переопределить proccesor контента (метод initContentProcessor), чтобы Grails proccess GSP с стандартного интервала SiteMesh завода
  • Если вы хотите получить больше возможностей (например, EXCLU DED модели) вам нужно будет переопределить весь метод doFilter использовать новый contentProcessor в contentProcessor.handles(webAppContext)
  • Добавить my.sitemesh.xml и decorators.xml в SRC/главная/веб-приложение/WEB-INF
  • Я добавил grailsApplication в сервлет контекст инициализации фильтра, так что вы можете использовать его в шаблонах FTL
  • Если вы хотите, чтобы пропустить некоторые макеты, добавлять условия окружающей средой во внутреннем Grails макете
+0

может быть, это не самое лучшее решение, но это работает ! Большое спасибо! –

Смежные вопросы