Announcement Announcement Module
Collapse
No announcement yet.
Spring MVC Noob help with site templates Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring MVC Noob help with site templates

    Hi all,
    I've used java and spring for quite a while, but always with message driven distributed systems, so I have little experience with the Web Tier short of editing existing frameworks. I've just finished a project that required C# MVC, and they have a great template system. You define a "master" file, then specify which one to use in your aspx file. I quite like this approach, but I'm not sure how to start with the Spring MVC. I want something like the following.

    +WEB-INF/views
    - parts/add.jsp
    - templates/layout.jsp

    Then in my layout.jsp file have something like the following.

    Code:
    <html>
    <head> stuff here</head>
    <body>
     <div id="content">
       <include:page/>
      </div>
    </body>
    </html>
    then in add.jsp, have something like this

    Code:
    <template="templates/layout.jsp"/>
    <form:form>
      <form:input .../>
    </form:form>
    then my content from add.jsp is merged with layout.jsp, which renders my page. I read up on templates, but there's only a couple of paragraphs, and no examples, so it's not clear to me if this can be accomplished or if I need to use a 3rd party tool such as velocity or freemaker. Any help or advice that points me to some examples and documentation would be greatly appreciated.

    Thanks,
    Todd

  • #2
    Just my 2 cents, but I've always stuck with Apache Tiles for this approach. It's easy to use, has great Spring support, allows me to stick with standard JSPs and integrates well with other web frameworks. Plus there's a plethora of examples and tutorials.

    hope that helps,

    Comment


    • #3
      Thanks for the help. I'm using tiles 2.1.3 with spring MVC 3 and everything works well. I want to use a default layout for all my URLs, which I'm defining via annotations on my controllers. I've tried using wild cards according to the example, but I just get an endless stack trace and my response is never rendered. Here is an example of what I'm trying to do.

      Code:
      <?xml version="1.0" encoding="ISO-8859-1" ?>
      <!DOCTYPE tiles-definitions PUBLIC
             "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
             "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
      <tiles-definitions>
      <!-- match every url -->
      	<definition name="**" template="/WEB-INF/layouts/default.jsp">
      		<put-attribute name="title" value="Tiles tutorial homepage" />
      		<put-attribute name="header" value="/WEB-INF/tiles/header.jsp" />
      		<put-attribute name="menu" value="/WEB-INF/tiles/menu.jsp" />
      		<put-attribute name="body" value="Get from regular view resolver" />
      		<put-attribute name="footer" value="/WEB-INF/tiles/footer.jsp" />
      	</definition>
      </tiles-definitions>

      Comment


      • #4
        Ok, so after a bit more reading on Tiles and a bit more of a play with it, this is the class I've come up with.

        Code:
        public class AutoTilesView extends TilesView {
        
        	private static final String PREFIX = "/WEB-INF/views/";
        	private static final String SUFFIX = ".jsp";
        	
        	/* (non-Javadoc)
        	 * @see org.springframework.web.servlet.view.tiles2.TilesView#renderMergedOutputModel(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
        	 */
        	@Override
        	protected void renderMergedOutputModel(Map<String, Object> model,
        			HttpServletRequest request, HttpServletResponse response)
        			throws Exception {
        		
        		//get the body tag and insert it into the context before calling the super.
        		
        		ServletContext servletContext = getServletContext();
        		TilesContainer container = ServletUtil.getContainer(servletContext);
        		
        		if (container == null) {
        			throw new ServletException("Tiles container is not initialized. " +
        					"Have you added a TilesConfigurer to your web application context?");
        		}
        		
        		AttributeContext attributeContext = container.getAttributeContext(request,
        		        response);
        	
        		StringBuilder builder = new StringBuilder();
        		builder.append(PREFIX);
        		builder.append(this.getUrl());
        		builder.append(SUFFIX);
        		
        		
        		attributeContext.putAttribute("body", Attribute.createTemplateAttribute(builder.toString()));
        		
        		super.renderMergedOutputModel(model, request, response);
        	}
        And the following web application context

        Code:
        	<!-- Tiles setup -->
        	<bean id="tilesConfigurer"
        		class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        		<property name="definitions">
        			<list>
        				<value>/WEB-INF/views/layouts/default.xml</value>
        			</list>
        		</property>
        	</bean>
        
        	<bean id="viewResolver"
        		class="org.springframework.web.servlet.view.UrlBasedViewResolver"
        		p:viewClass="com.inventory.web.spring.AutoTilesView" />
        Then here's my default.xml file

        Code:
        <?xml version="1.0" encoding="ISO-8859-1" ?>
        <!DOCTYPE tiles-definitions PUBLIC
               "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
               "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
        <tiles-definitions>
        	<definition name="*/*" template="/WEB-INF/views/layouts/default.jsp">
        		<put-attribute name="title" value="Tiles tutorial homepage" />
        		<put-attribute name="header" value="/WEB-INF/views/tiles/header.jsp" />
        		<put-attribute name="menu" value="/WEB-INF/views/tiles/menu.jsp" />
        		<!--<put-attribute name="body" value="/WEB-INF/views/parts/list.jsp" />-->
        		<put-attribute name="footer" value="/WEB-INF/views/tiles/footer.jsp" />
        	</definition>
        </tiles-definitions>
        And my layout jsp

        Code:
        <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
        <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
        <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
        <html>
        <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>Insert title here</title>
        </head>
        <body>
        <table>
          <tr>
            <td colspan="2">
              <tiles:insertAttribute name="header" />
            </td>
          </tr>
          <tr>
            <td>
              <tiles:insertAttribute name="menu" />
            </td>
            <td>
              <tiles:insertAttribute name="body" />
            </td>
          </tr>
          <tr>
            <td colspan="2">
              <tiles:insertAttribute name="footer" />
            </td>
          </tr>
        </table>
        </body>
        </html>
        This gets the job done, each Controller renders the jsp associated with it like the default JSTL view rendering class.

        Comment

        Working...
        X