SiteMesh 3 Documentation

repository·master·Indexed 19 days ago

https://github.com/sitemesh/sitemesh3

A high-performance web-page decoration framework for applying consistent layouts to HTML content. SiteMesh 3 supports runtime integration in Java web applications via Servlet Filters or Spring MVC ViewResolvers, as well as offline use for static site generation. It includes integration examples for Spring Boot, Micronaut, Apache Struts, and Javalin, along with tools for performance benchmarking using LoadGen.

Tokens
11K
Snippets
29
Records
47
Agent score
66%

What's inside SiteMesh 3

  1. What is SiteMesh 3?

    master

    SiteMesh 3 is a web-page layout and decoration framework used to create consistent look-and-feel, navigation, and layouts across a website.

    Core Capabilities:

    • Interception: It intercepts requests to static or dynamically generated HTML pages.
    • Decoration: It processes content and merges it with one or more decorators to build the final result.
    • Composition: It can be used to compose large pages from smaller pages and layouts.
    • Versatility: It can be used in Java-based web applications or as an offline job for static site generation.
    • Extensibility: It features a new content processor architecture, supports decorator chaining, and provides reusable building blocks like ContentBufferingFilter and HTML TagProcessor.
  2. How SiteMesh 3 works in web applications

    master

    SiteMesh 3 operates as a Servlet Filter. It intercepts the HTML response (the "content") generated by your application before it is sent to the browser.

    The Workflow:

    1. Interception: The Servlet engine handles a request normally. SiteMesh intercepts the resulting HTML.
    2. Extraction: SiteMesh extracts specific properties from the content, typically the contents of the <title>, <head>, and <body> tags.
    3. Decoration: These extracted properties are passed to a Decorator (a template defining the common look and feel).
    4. Merging: The decorator uses placeholders to insert the extracted properties into its own structure, creating the final merged HTML sent to the user.

    SiteMesh is technology-agnostic; it works with static files, JSPs, Servlets, or any MVC framework, as long as they are served by a Servlet engine.

  3. How MicronautSiteMeshContext works

    master

    The MicronautSiteMeshContext is the bridge between SiteMesh 3 and Micronaut's view layer. It extends BaseSiteMeshContext (the servlet-free core used in offline mode).

    It handles the rendering of decorator templates by delegating back to the wrapped ViewsRenderer. This allows decorators to be treated as ordinary view templates located under src/main/resources/views/decorators/.

    Important: Views located under the decorators/ directory are never decorated themselves, which prevents infinite recursion.

  4. Use the SiteMesh Java API for offline generation

    master
    For advanced integration, SiteMesh 3 provides a Java API that can be used to apply decorators as an offline task. This API can be embedded directly into Java applications or invoked from higher-level languages like Groovy, Scala, or JRuby. This allows you to integrate SiteMesh decoration directly into your custom build pipelines or application logic.
  5. Quickstart: Set up a SiteMesh 3 project with Gradle

    master

    To get started with SiteMesh 3, you can use a Java application server managed by Gradle.

    1. Create a project directory.
    2. Create a build.gradle file in that directory with the following configuration to use the war plugin and gretty for running the server:
    plugins {
        id 'war'
        id "org.gretty" version "4.0.3"
    }
    
    gretty.contextPath = '/'
    
    repositories {
        mavenCentral()
    }
    1. Add SiteMesh as a dependency. You can either manually place the SiteMesh JAR in src/main/webapp/WEB-INF/lib or add it to your build.gradle dependencies block for automatic management:
    dependencies {
        implementation 'org:sitemesh:sitemesh:3.2.0-M2'
    }
    plugins {
        id 'war'
        id "org.gretty" version "4.0.3"
    }
    
    gretty.contextPath = '/'
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation 'org:sitemesh:sitemesh:3.2.0-M2'
    }
  6. Add JSTL dependencies for Jakarta EE 10+

    master

    If your JSP pages use JSTL tags and you are upgrading to Jakarta EE 10 or higher, you must explicitly include both the JSTL API and the implementation, as they are no longer bundled together in the same artifact.

    dependencies {
        // JSTL 3.0 for Jakarta EE 10
        implementation 'jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:3.0.0'
        implementation 'org.glassfish.web:jakarta.servlet.jsp.jstl:3.0.1'
    }
  7. Configure SiteMesh 3 via XML

    master

    You can configure SiteMesh 3 using a /WEB-INF/sitemesh3.xml file. This file allows you to define the decorator selector, the default decorator prefix, error page handling, and dispatch modes. You can also define path-based mappings to apply specific decorators or exclude certain paths from decoration.

    Default Configuration Example

    <sitemesh>
      <decorator-selector>org.sitemesh.config.MetaTagBasedDecoratorSelector</decorator-selector>
      <decorator-prefix>/WEB-INF/decorators/</decorator-prefix>
      <include-error-pages>true</include-error-pages>
      <dispatch-mode>detect</dispatch-mode>
    </sitemesh>

    Decorator Mapping Example

    Use <mapping> to apply decorators to specific paths or to exclude paths:

    <sitemesh>
      <mapping path="/*" decorator="default.html"/>
      <mapping path="/Pretty/*" decorator="bootstrap.jsp"/>
      <mapping path="/assets/*" exclude="true" />
    </sitemesh>
    <sitemesh>
      <decorator-selector>org.sitemesh.config.MetaTagBasedDecoratorSelector</decorator-selector>
      <decorator-prefix>/WEB-INF/decorators/</decorator-prefix>
      <include-error-pages>true</include-error-pages>
      <dispatch-mode>detect</dispatch-mode>
    </sitemesh>
  8. Use the SiteMesh Ant Task for offline processing

    master

    The sitemesh.jar includes a custom Ant task (SiteMeshTask) for offline content decoration. You can use it to process files via a configuration file or by defining specific decorator mappings within your Ant build script.

    1. Register the Task

    Use <taskdef/> to register the task in your build.xml:

    <taskdef name="sitemesh" 
             classname="org.sitemesh.ant.SiteMeshTask" 
             classpath="path/to/sitemesh-3.x.jar"/>

    2. Configure SiteMesh

    You can use a SiteMesh configuration file to externalize decorator mappings from your Ant script. A simple mapping looks like this:

    <sitemesh>
      <mapping path="/*" decorator="/decorators/main.html"/>
    </sitemesh>

    3. Execute the Task

    You can run the task in several ways:

    Option A: Using directory-level configuration Provide srcdir, config, and destdir to process all files in a directory matching specific include/exclude patterns.

    Option B: Using <sitemeshfileset> Use <sitemeshfileset> for granular control. This allows you to specify different source directories (dir) and even associate a specific decorator with each fileset.

    <target name="my-target">
      <sitemesh destdir="site/documentation">
        <sitemeshfileset dir="documentation" decorator="decorators/private.html">
          <include name="private/*.html"/>
        </sitemeshfileset>
      </sitemesh>
    </target>
  9. Configure SiteMesh 3 using XML

    master

    You can use an XML configuration file for easy setup and automatic reloading when the file changes. The configuration file must be placed at /WEB-INF/sitemesh3.xml within your web application.

    Common configuration elements include:

    • <mapping>: Maps a path to a decorator.
    • <mapping path="..." exclude="true"/>: Excludes a path from being decorated.
    • <mime-type>: Defines which Content-Type headers SiteMesh should intercept (defaults to text/html).
    • <content-processor>: Used to register custom tag-rule-bundle classes.
    <sitemesh>
      <mapping path="/*" decorator="decorator.html"/>
      <mapping path="/admin/*" decorator="admin-decorator.html"/>
    </sitemesh>
  10. Create a SiteMesh decorator

    master

    A decorator is a template that defines the site's layout and style. It must use the <sitemesh:write property="..."/> tag to act as a placeholder for content extracted from the original page.

    Minimum Required Decorator

    At a minimum, your decorator should include placeholders for title, head, and body:

    <html>
      <head>
        <title><sitemesh:write property="title"/></title>
        <sitemesh:write property="head"/>
      </head>
      <body>
        <sitemesh:write property="body"/>
      </body>
    </html>

    Advanced Decorator Example

    You can add CSS, headers, and complex layouts. The decorator can be a static .html file or a dynamic template (JSP, FreeMarker, etc.) served by the Servlet engine.

    <html>
      <head>
        <title>SiteMesh example: <sitemesh:write property="title"/></title>
        <style>
          body { font-family: arial, sans-serif; background-color: #ffffcc; }
          .mainBody { padding: 10px; border: 1px solid #555555; }
        </style>
        <sitemesh:write property="head"/>
      </head>
      <body>
        <h1 class="title">SiteMesh example site: <sitemesh:write property="title"/></h1>
        <div class="mainBody">
          <sitemesh:write property="body"/>
        </div>
        <div class="disclaimer">Site disclaimer. This is an example.</div>
      </body>
    </html>
    <html>
      <head>
        <title>SiteMesh example: <sitemesh:write property="title"/></title>
        <style>
          /* Some CSS */
         body { font-family: arial, sans-serif; background-color: #ffffcc; }
         h1, h2, h3, h4 { text-align: center; background-color: #ccffcc;
                          border-top: 1px solid #66ff66; }
         .mainBody { padding: 10px; border: 1px solid #555555; }
         .disclaimer { text-align: center; border-top: 1px solid #cccccc;
                       margin-top: 40px; color: #666666; font-size: smaller; }
        </style>
        <sitemesh:write property="head"/>
      </head>
      <body>
    
        <h1 class="title">SiteMesh example site: <sitemesh:write property="title"/></h1>
    
        <div class="mainBody">
          <sitemesh:write property="body"/>
        </div>
    
        <div class="disclaimer">Site disclaimer. This is an example.</div
    
      </body>
    </html>
  11. Fix JSP rendering in Spring Boot with Tomcat 11

    master

    When using Spring Boot with embedded Tomcat 11, JSP pages may return empty responses because Spring's InternalResourceView uses RequestDispatcher.forward(), which commits the response in Tomcat 11.

    To fix this, you must configure your InternalResourceViewResolver to use include instead of forward by setting alwaysInclude(true). This works for JSP views; other template engines like Thymeleaf or FreeMarker do not require this change.

    @Bean
    public InternalResourceViewResolver jspViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/jsp/");
        resolver.setSuffix(".jsp");
        resolver.setAlwaysInclude(true);  // Use include instead of forward
        return resolver;
    }
  12. Configure Spring Boot Starter for SiteMesh

    master

    The spring-boot-starter-sitemesh (Spring Boot 4.x) provides two integration styles via the sitemesh.integration property:

    1. view-resolver (Default): Decorates everything rendered through Spring MVC's ViewResolver/View pipeline (Thymeleaf, FreeMarker, JSP, etc.). This is the safest option for Tomcat 11+ and is required for frameworks like Grails where view rendering forwards internally.
    2. filter: Decorates any text/html servlet response, including static resources and container error pages. Use this if you need to decorate content that does not flow through Spring MVC views. Note: On Tomcat 11+, JSP views require InternalResourceViewResolver.setAlwaysInclude(true) when using this mode.

    YAML Configuration Example

    sitemesh:
      # integration: filter            # default is view-resolver
      decorator:
        prefix: /decorators/          # location of decorators
        metaTag: decorator            # <meta name="decorator"> tag
        default: default.html         # applied to /*
        attribute:                    # request attribute for selection
        tagRuleBundles:               # extra TagRuleBundle classes
        exclusions: /assets/*         # paths excluded (filter integration only)
        mappings:
          - path: /admin/*
            decorator: admin.html
          - path: /board/*
            decorator: board.html,default.html   # chained decorators
      dispatchMode: detect            # include | forward | detect
      includeErrorPages: true

    Important Notes:

    • sitemesh.decorator.exclusions only applies to the filter integration.
    • Decorators can be chained using comma-separated values (e.g., board.html,default.html).
    • Decorator paths starting with / are treated as static resources (e.g., in src/main/resources/static/). Paths without a leading / are treated as Spring MVC logical view names (e.g., Thymeleaf templates).
    sitemesh:
      decorator:
        prefix: /decorators/
        metaTag: decorator
        default: default.html
        exclusions: /assets/*
        mappings:
          - path: /admin/*
            decorator: admin.html
          - path: /board/*
            decorator: board.html,default.html
      dispatchMode: detect