Giter Site home page Giter Site logo

sitemesh3's Introduction

SiteMesh 3: Official repository

Kiss Good Bye to Boilerplate HTML Code!!

Get Up and Running with a Single JAR. No Configuration Needed, Just Drop it in!

Learn SiteMesh 3 in 5 Minutes

Currently maintained versions:

3.1.x 3.2.x
Java 8+ Java 17+
Servlet API 3.0-4.0.1 Jakarta EE 10
Spring Boot 2.x Support Spring Boot 3.x Support
3.1.x Master Branch
Java Docs
Download 3.1.1 Download 3.2.1

Website / Documentation (Built with Offline Generator)

Installing:

You can either download the release build and simply add the sitemesh jar to your classpath or use Gradle or Maven.

dependencies {
    // ... other dependencies
    runtimeOnly 'org.sitemesh:sitemesh:3.2.1'
}
<dependencies>
    <!-- ... other dependencies -->
    <dependency>
        <groupId>org.sitemesh</groupId>
        <artifactId>sitemesh</artifactId>
        <version>3.2.1</version>
    </dependency>
</dependencies>

or if you are using Spring Boot, use the config free starter (see example application):

dependencies {
    // ... other dependencies
    runtimeOnly 'org.sitemesh:spring-boot-starter-sitemesh:3.2.1'
}
<dependencies>
    <!-- ... other dependencies -->
    <dependency>
        <groupId>org.sitemesh</groupId>
        <artifactId>spring-boot-starter-sitemesh</artifactId>
        <version>3.2.1</version>
    </dependency>
</dependencies>

Snapshots:

If you would like to use the latest features, you can use the latest build from our snapshot repository:

repositories {
    mavenCentral() 
    maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
dependencies {
    runtimeOnly 'org.sitemesh:sitemesh:3.2.1-SNAPSHOT'
}

or

dependencies {
    runtimeOnly 'org.sitemesh:sitemesh:3.1.1-SNAPSHOT'
}

Building:

You can build each respective version by checking out that particular branch as follows:

3.1.x

git clone https://github.com/sitemesh/sitemesh3
git checkout 3.1.x
./gradlew jar

3.2.x

git clone https://github.com/sitemesh/sitemesh3
./gradlew jar

a jar will be available in the following location

./sitemesh/build/libs/sitemesh-XX.XX.XX-SNAPSHOT.jar

SiteMesh 3 Overview

  • SiteMesh is a web-page layout and decoration framework and web- application integration framework to aid in creating sites consisting of pages for which a consistent look/feel, navigation and layout scheme is required.
  • SiteMesh intercepts requests to any static or dynamically generated HTML page requested through the web-server, processes the content and then merges it with one or more decorators to build the final result.
  • SiteMesh can also be used compose large pages of smaller pages and layouts.
  • SiteMesh is fast. Really fast.
  • SiteMesh can be used in Java based web-applications, or applied to content as an offline job.
  • SiteMesh is extensible.

What's New in SiteMesh 3?

SiteMesh 3 has been completely rebuilt from the ground up. It's more efficient, easier to use and extensible. While the code is new, it still holds the same values of SiteMesh 2, namely simplicity, robustness and performance.

New Content Processor Architecture

The internals of how SiteMesh processes content have been radically changed. The result is typically a 3X gain in throughput and half the memory usage (based on some typical sized samples).

The new architecture also opens up new possibilities for upcoming features...

Decorator Chaining

Decorators can now be chained together in a website. That is, content can be decorated, then decorated again (and again). The new architecture of the content processor means there is little overhead in applying multiple decorators.

No Tie-ins to Templating Systems

No longer do you need to commit to JSP or Velocity to build your decorators. Like content, decorators can be generated by any technology - even static .html files.

Simplified Configuration

Want to configure purely through Java code, through XML, through Spring, or even by convention. It's your choice. And it's easy to plug in your own configuration mechanism.

Spring Boot AutoConfiguration Starter

Use the Spring Boot Starter and be up and running in seconds.

Offline Site Generation

Working Example Here

SiteMesh comes with tools to allow you decorators to content for static websites as an offline task. This can be invoked from a command line tool, an Ant task or through a Java API.

Can be used to cut the cost of hosting (no Java runtime needed on servers) or simplify distribution (e.g. include web-site as part of a downloaded package).

Code Modernization

Under the hood, over 10 years worth of cruft has been cleaned up. This means a simpler API. And many long-standing design decisions have been revisited, which has made the things above possible, and opens the possibility of your own extensions.

The various extension APIs have been revisited to make the easier to understand, with useful hooks and clear documentation.

Reusable Core Building Blocks

Many of the underlying building blocks of SiteMesh are useful to other applications. These have been decoupled from the code, allowing you to reuse them in your own application, even if you don't intend to use SiteMesh.

  • The ContentBufferingFilter is a reusable Servlet Filter that intercepts responses and allows modifications to be made to the content.
  • The HTML TagProcessor is a high-performant and extensible tag parser that allows for extraction and transformations of content.

Relicensed under the Apache Software License v2.0

This license is used much more widely and approved by many organizations

Getting Started with SiteMesh 3

Introduction

This tutorial is a quick introduction to using SiteMesh3 in a web-application. It covers:

  • A high level overview of how SiteMesh3 works
  • Installation and configuration
  • Building and applying a simple decorator It is recommended you read the high level SiteMesh 3 Overview before this tutorial.

SiteMesh in web applications

In a web application, SiteMesh acts as a Servler Filter. It allows requests to be handled by the Servlet engine as normal, but the resulting HTML (referred to as the content) will be intercepted before being returned to the browser.

The intercepted content has certain properties extracted (typically the contents of the <title>, and tags and is then passed on to a second request that should return the common look and feel for the site (referred to as the decorator). The decorator contains placeholders for where the properties extracted from the content should be inserted.

Under the hood, a key component of the SiteMesh architecture is the content processor. This is an efficient engine for transforming and extracting content from HTML content. For most users, it's fine to use it as it comes, but it is also possible to define your own transformation and extraction rules.

SiteMesh does not care what technologies are used to generate the content or the decorator. They may be static files, Servlet, JSPs, other filters, MVC frameworks, etc. So long as it's served by the Servlet engine, SiteMesh can work with it.

Dependencies

Running SiteMesh requires at least:

  • JDK 1.8
  • A Servlet 3.x compliant container
  • The SiteMesh runtime library
  • The SiteMesh library should be downloaded and placed in /WEB-INF/lib/.

Setup

Insert the SiteMesh Filter in /WEB-INF/web.xml:

<web-app>

  <filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>org.sitemesh.config.ConfigurableSiteMeshFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

</web-app>

Deploy the web-application to your Servlet container. From this point onwards, this tutorial assumes the web-app is running at http://myserver/.

Creating a decorator

The decorator contains the common layout and style that should be applied to the pages in the web application. It is a template that contains place holders for the content's <title>, and elements.

At the bare minimum, it should contain:

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

The <sitemesh:write property="..."/> tag will be rewritten by SiteMesh to include properties extracted from the content. There are more properties that can be extracted from the content and it's possible to define your own rules - that will be covered in another tutorial.

The bare minimum decorator isn't very useful. Let's add some style and a bit of common layout.

Create the file /decorator.html in your web-app, containing:

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

In this example, the decorator is a static .html file, but if you want the decorator to be more dynamic, technologies such as JSP, FreeMarker, etc can be used. SiteMesh doesn't care - it just needs a path that can be served content by the Servlet engine.

Configuration

SiteMesh needs to be configured to know about this decorator and what it should do with it.

The configuration file should be created at /WEB-INF/sitemesh3.xml:

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

This tells SiteMesh that requests matching the path /* (i.e. all requests) should be decorated with /decorator.html that we just created.

If you don't like the idea of having to use XML to configure SiteMesh, don't worry - there are alternative mechanisms including directly in WEB-INF/web.xml, programatically through a Java API, through Spring, by naming convention, or any custom way you may choose to plug in. These are explained further in another article.

Creating some content

Now to create some content. This is defined in plain HTML content. Create /hello.html:

<html>
  <head>
    <title>Hello World</title>
    <meta name="description" content="A simple page">
  </head>
  <body>
    <p>Hello <strong>world</strong>!</p>
  </body>
</html>

Like the decorator, the content may be static files or dynamically generated by the Servlet engine (e.g. JSP).

The result

Pointing your browser to http://myserver/hello.html will serve the content you just created, with the decorator applied. The resulting merged HTML will look like this:

<html>
  <head>
    <title>SiteMesh example: Hello World</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>
    <meta name="description" content="A simple page">
  </head>
  <body>

    <h1 class="title">SiteMesh example site: Hello World</h1>

    <div class="mainBody">
      <p>Hello <strong>world</strong>!</p>
    </div>

    <div class="disclaimer">Site disclaimer. This is an example.</div>

  </body>
</html>

As you can see, the <title>, and have been extracted from the content and inserted into the decorator template.

Summary

A quick recap:

  • SiteMesh is installed by dropping the library jar in /WEB-INF/lib and creating a filter (with mapping) in /WEB-INF/web.xml
  • It can be configured by creating a /WEB-INF/sitemesh3.xml file, or through other configuration methods
  • The filter intercepts requests to Content, runs it through the Content Processor and merges with a Decorator
  • The Content is defined by an HTML page, that contains the vanilla HTML content of the site
  • The Decorator is also defined by an HTML page, that contains the look and feel of the site, and placeholder sitemesh:write tags to indicate where the Content should be merged in
  • The Content Processor contains the rules for extracting and transforming the content - it has some simple default rules and can be customized

Configuring SiteMesh 3

SiteMesh supports two main approaches to configurations - XML or Java. It's up to you which you use. In fact, you can even use them both.

Html

  • Simplest to get started with
  • Use meta tags to define your decorators and skip configuration completely.
  • Avoids need for any configuration file

XML

  • Easy to get started with
  • Automatically reloads when config file changes
  • Does not require Java programming

Java

  • Allows for greater customization of SiteMesh
  • Avoids yet another configuration file
  • Can be used from higher level languages such as JRuby, Groovy, Scala...

Html Configuration

All you have to do is add a meta tag inside of your web page and SiteMesh will do the rest of the work!

Example

<html>
  <head>
      <title>Hello World</title>
      <meta name="decorator" content="decorator.html"/>
  </head>
  <body>
    <h1>This page will be decorated :)</h1>
  </body>
</html>

XML based configuration

The configuration file should live in /WEB-INF/sitemesh3.xml in your web-application.

Example

<sitemesh>
  <mapping path="/*" decorator="decorator.html"/>
  <mapping path="/admin/*" decorator="admin-decorator.html"/>
</sitemesh>

Java based configuration

To use the Java based configuration, subclass org.sitemesh.config.ConfigurableSiteMeshFilter and overload the applyCustomConfiguration(SiteMeshFilterBuilder builder) method. You shall be passed an object that you can use to configure SiteMesh. You then deploy this filter in to your web-application.

Example

public class MySiteMeshFilter extends ConfigurableSiteMeshFilter {
    @Override
    protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
        builder.addDecoratorPath("/*", "decorator.html")
                .addDecoratorPath("/admin/*", "admin/decorator.html");
    }
}

Note: The SiteMeshFilterBuilder class supports a chainable API where each method returns an instance of itself. This is a convenience, but you don't have to use this style.

Note: If you also have an XML config file, SiteMesh will load this before calling applyCustomConfiguration(). This allows you to use XML for some configuration and Java for more advanced aspects.

Configuring Decorator Mappings

This is the most common configuration applied to SiteMesh - mapping which decorators are applied based on the paths.

Things you can do:

  • Map a default decorator to all paths
  • Map a decorator to a specific path
  • Map multiple decorators to a path - each decorator is applied to the result of the previous Exclude a path from being decorated

XML

<sitemesh>
  <!-- Map default decorator. This shall be applied to all paths if no other paths match. -->
  <mapping decorator="default-decorator.html"/>

  <!-- Map decorators to path patterns. -->
  <mapping path="/admin/*" decorator="another-decorator.html"/>
  <mapping path="/*.special.jsp" decorator="special-decorator.html"/>

  <!-- Alternative convention. This is more verbose but allows multiple decorators
       to be applied to a single path. -->
  <mapping>
    <path>/articles/*</path>
    <decorator>article.html</decorator>
    <decorator>rwo-page-layout.html</decorator>
    <decorator>common.html</decorator>
  </mapping>

  <!-- Exclude path from decoration. -->
  <mapping path="/javadoc/*" exclude="true"/>
  <mapping path="/brochures/*" exclude="true"/>

</sitemesh>

Java

public class MySiteMeshFilter extends ConfigurableSiteMeshFilter {

  @Override
  protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
           // Map default decorator. This shall be applied to all paths if no other paths match.
    builder.addDecoratorPath("/*", "default-decorator.html") 
           // Map decorators to path patterns. 
           .addDecoratorPath("/admin/*", "another-decorator.html")
           .addDecoratorPath("/*.special.jsp", "special-decorator.html")
           // Map multiple decorators to the a single path.
           .addDecoratorPaths("/articles/*", "article.html",
                                             "two-page-layout.html", 
                                             "common.html")
           // Exclude path from decoration.
           .addExcludedPath("/javadoc/*")
           .addExcludedPath("/brochures/*");
  }
}

Advanced Configuration

For most users, the decorator mappings above should be enough. But if you want more options...

MIME Types

By default, SiteMesh will only intercept responses that set the Content-Type HTTP header to text/html.

This can be altered to allow SiteMesh to intercept responses for other types. This is only applicable for the SiteMesh Filter - it is ignored by the offline site builder.

XML

<sitemesh>
  <mime-type>text/html</mime-type>
  <mime-type>application/vnd.wap.xhtml+xml</mime-type>
  <mime-type>application/xhtml+xml</mime-type>
  ...
</sitemesh>

Java

public class MySiteMeshFilter extends ConfigurableSiteMeshFilter {

  @Override
  protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
    builder.setMimeTypes("text/html", "application/xhtml+xml", "application/vnd.wap.xhtml+xml");
  }

}

Deploying Tag Rule Bundles

An advanced feature of SiteMesh is the ability to define custom rules that manipulate tags on a page. These are classes that implement org.sitemesh.content.tagrules.TagRuleBundle.

XML

<sitemesh>
  <content-processor>
    <tag-rule-bundle class="com.something.CssCompressingBundle"/>
    <tag-rule-bundle class="com.something.LinkRewritingBundle"/>
  </content-processor>
  ...
</sitemesh>

Java

public class MySiteMeshFilter extends ConfigurableSiteMeshFilter {
    
  @Override
  protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
    builder.addTagRuleBundles(new CssCompressingBundle(), new LinkRewritingBundle());
  }

}

Building Offline Websites with SiteMesh 3

A new feature in SiteMesh 3 is being able to apply decorators to content as an offline task, typically as part of a build step.

If both your content and your decorators are static, this offers a few benefits:

Allows final content to be distributed as pre-generated folder. Useful for including documentation with products without having to include a full Servlet compliant web-server. Cuts down server loads - most web-server architectures are optimized for serving static files. Provides more flexibility on where you can host content. It's also possible to reuse decorators and configuration between a web application that generates decorated content on the fly, and offline generated files.

Usage

There are a few different approaches to invoking the SiteMesh offline generator:

  1. Command line interface
  2. Apache Ant task
  3. Java API (this can be embedded in applications, or used from higher level languages such as JRuby, Groovy or Scala)

Each of these can have the mappings of the decorators passed directly to them, or load from the SiteMesh configuration file.

Use the approach that suits your project.

Command line interface

You can invoke the command line interface by running the executable sitemesh.jar. It requires Java 5 but no other dependencies.

Invoking on it's own will output a detailed help message:

java -jar sitemesh-3.x.jar

Arguments

The following arguments need to be passed to the command line:

-src Required Path to source directory, containing content and decorators -dest Required Path to destination directory, where decorated content will be written -dest Required Path to destination directory, where decorated content will be written -config One of these Path to configuration file -decoratorMapping TODO FILE1 FILE2 FILE3... Required List of content files to apply decorators to. These must be relative to the src directory

Example

java -jar sitemesh-3.x.jar -src project/src -config project/sitemesh.xml -dest project/build index.html page1.html page2.html

Ant Task

Overview

The sitemesh.jar comes prepackaged with a custom Ant task that can be used for offline processing. In the following examples, we're going to look at how to install and use the SiteMeshTask to generate static content in the offline mode.

SiteMeshTask

The SiteMeshTask defines the following attributes:

  1. destDir - The output folder in which all of the decorated files will be placed.
  2. config - The location of the SiteMesh configuration file.
  3. srcdir - The source directory which contains all of the files to be decorated.
  4. includes - An Ant style filter of what files to include.
  5. excludes - An Ant style filter of what files to exclude.

The SiteMeshTask can also accept the following child nodes:

  1. fileset - The standard Ant FileSet that will use the srcdir of the sitemesh node.
  2. sitemeshfileset - A custom SiteMesh FileSet that supports an additional attribute called "decorator" which can be used to associate a decorator with the given FileSet.

Getting started!

The below provides a high level outline of what steps we're going to cover in this section.

  1. Create a SiteMesh configuration file.
  2. Register the SiteMeshTask with Ant
  3. Define the node.
  4. Execute Ant
1. Creating the SiteMesh configuration file

The SiteMeshTask can be given a configuration file to tell SiteMesh how to decorate files. The power of this feature is that the configuration is then externalized from the build.xml file. In our first two examples, we're going to show how to use this form of the SiteMeshTask. Below is a very simple SiteMesh configuration file that applies the main.html decorator to all pages.

<sitemesh>
  <mapping path="/*" decorator="/decorators/main.html"/>
</sitemesh>
2. Registering SiteMeshTask with Ant

In order to use SiteMesh from within Ant, the first thing you will need to do is register the SiteMeshTask with Ant using the following declaration.

<project name="my-ant-project">

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

  ...

</project>

For more information on registering custom tasks within Ant, please see Writing Ant Tasks.

3. Define the node.

Now that we've created the SiteMesh configuration file and registered the SiteMeshTask with Ant, it's time to start using SiteMesh within our tasks.

Using the sitemesh task without a fileset.

Let's look at how to provide with a configuration file and tell it what directories to include or exclude.

In this example, we're going to process all of the files stored in "project/src" and place the decorated files into "project/build".

<project name="my-ant-project">

  <target name="my-target">
    <sitemesh srcdir="project/src"
              config="project/sitemesh.xml"
              destdir="project/build"
              includes="*/.html"
              excludes="decorators/*"/>
  </target>

</project>

The benefit to the above is that all configuration is externalized from the build.xml file.

Using the sitemesh task with the sitemeshfileset

In the below example, multiple source folders are used by provided a sitemeshfileset. This provides greater control over what folders should be included or excluded, but still leverage a common destination folder and configuration file.

<project name="my-ant-project">


  <target name="my-target">

    <sitemesh destdir="site/documentation"
              config="config/sitemesh.xml">

      <sitemeshfileset dir="documentation">
        <include name="*/.html"/>
        <exclude name="private/*"/>
      </sitemeshfileset>

      <sitemeshfileset dir="presentation">
        <include name="*/.html"/>
      </sitemeshfileset>

    </sitemesh>
  </target>

</project>

Using the sitemesh task with the sitemeshfileset with an associated decorator

In our final example, a decorator will be used on each sitemeshfileset.

<project name="my-ant-project">

  <target name="my-target">
    <sitemesh destdir="site/documentation">
      <sitemeshfileset dir="documentation"
                       decorator="decorators/private.html">
        <include name="private/*.html"/>
      </sitemeshfileset>
    </sitemesh>
  </target>

</project>

sitemesh3's People

Contributors

codeconsole avatar ghillert avatar joewalnes avatar msgilligan avatar musketyr avatar pluppens avatar rburton avatar rvowles avatar saviomotac avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sitemesh3's Issues

Embedded configuration in Spring XML

Allow SiteMesh to be configured directly in a Spring XML config file, so as not to force Spring users to add yet another config file.

See design doc for example: http://wiki.github.com/sitemesh/sitemesh3/design-doc-configuration

Implementation notes:

java.lang.IllegalStateException: STREAM when serving static content (Google Chrome on local App Engine only-not production)

Environment: Google App Engine
This only occurs on the local development server. It does not occur on the deployed app. And it only happens in the Google Chrome browser.

** This Error is specific to Sitemesh, because if I remove Sitemesh from the web.xml, everything works fine.

For some reason I am getting an java.lang.IllegalStateException: STREAM when I visit a page in Chrome only. Oddly enough, page is fine when I view in firefox.

Appears to be happening when I serve static content:

WARNING: /resources/dijit/themes/tundra/tundra.css
java.lang.IllegalStateException: STREAM
at org.mortbay.jetty.Response.getWriter(Response.java:616)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at org.sitemesh.webapp.contentfilter.ContentBufferingFilter.writeOriginal(ContentBufferingFilter.java:201)
at org.sitemesh.webapp.contentfilter.ContentBufferingFilter.bufferAndPostProcess(ContentBufferingFilter.java:184)
at org.sitemesh.webapp.contentfilter.ContentBufferingFilter.doFilter(ContentBufferingFilter.java:126)
at org.sitemesh.config.ConfigurableSiteMeshFilter.doFilter(ConfigurableSiteMeshFilter.java:163)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)

Results from this block of code:

    if (responseBuffer.isBufferStreamBased()) {
        PrintWriter writer = new PrintWriter(response.getOutputStream());
        writer.append(buffer);
        writer.flush(); // Flush writer to underlying outputStream.
        response.getOutputStream().flush();
    } else {
        PrintWriter writer = response.getWriter();
        writer.append(buffer);
        response.getWriter().flush();
    }

apparently responseBuffer.isBufferStreamBased() isn't working?
-- not necessarily the case.

Forcing it to write to a stream (changing the sitemesh code) results in a NO CONTENT illegal state exception when calling
writer.flush();

response.isCommitted() returns true prior to entering this block of code.

This error occurs even though the url has no sitemesh3 mappings associated with it.
The only decorator defined:

sitemesh3 not decorating error pages

if you set an error-page element in web.xml sitemesh3 won't decorate that file.

ERROR in the filter-mapping does nothing.
Hopefully someone can confirm this as well - just in case I might have missed something.

Fix org.sitemesh.html.Sm2HtmlContentProcessorTest

The test fails now that the Sm2TagRuleBundle has been fixed.

Failed tests: 
  testBody(org.sitemesh.html.DataDrivenSuiteBuilder$AssertTrimmedTest): null expected:<[]> but was:<[<html>

</html>]>
  testBody(org.sitemesh.html.DataDrivenSuiteBuilder$AssertTrimmedTest): null expected:<[]> but was:<[<html>

</html>]>
  testBody(org.sitemesh.html.DataDrivenSuiteBuilder$AssertTrimmedTest): null expected:<[]> but was:<[<html>

</html>]>
  testBody(org.sitemesh.html.DataDrivenSuiteBuilder$AssertTrimmedTest): null expected:<[]> but was:<[<html>

</html>]>
  testBody(org.sitemesh.html.DataDrivenSuiteBuilder$AssertTrimmedTest): null expected:<[]> but was:<[<HTML>

</HTML>]>

“Not Modified” header followed by unexpected content body

When using sitemesh 3.0.0 with struts2 behind an apache http server, whenever I fetch content from the /struts context and get a 304 "Not Modified", I also receive the file body in the response. This corrupts any file request after that one, resulting in an unstable web site.
Please see this post on StackOverflow for the details: http://stackoverflow.com/questions/24430135/not-modified-header-followed-by-unexpected-content-body

I have done some investigations in the sources and found out that, although sitemesh might not be held responsible for this behavior, still it handles "not modified" files its own way, by forcing struts into writing them to the response body.

Please do not underestimate this problem. It really makes web sites unusable, especially when coupled with some plugin that pulls big files from the /struts context, like the struts2-jquery plugin. In my case, it corrupts my own javascript and the site doesn't respond anymore to user clicks.

Test Failures

When building SM3, I see 5 test failures:

Failed tests: 
  testBody(org.sitemesh.html.DataDrivenSuiteBuilder$AssertTrimmedTest): null expected:<[]> but was:<[<html>

</html>]>
  testBody(org.sitemesh.html.DataDrivenSuiteBuilder$AssertTrimmedTest): null expected:<[]> but was:<[<html>

</html>]>
  testBody(org.sitemesh.html.DataDrivenSuiteBuilder$AssertTrimmedTest): null expected:<[]> but was:<[<html>

</html>]>
  testBody(org.sitemesh.html.DataDrivenSuiteBuilder$AssertTrimmedTest): null expected:<[]> but was:<[<html>

</html>]>
  testBody(org.sitemesh.html.DataDrivenSuiteBuilder$AssertTrimmedTest): null expected:<[]> but was:<[<HTML>

</HTML>]>

Tests run: 700, Failures: 5, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] SiteMesh parent POM ............................... SUCCESS [0.620s]
[INFO] SiteMesh library .................................. FAILURE [8.155s]
[INFO] SiteMesh example: Hello world web-app ............. SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.965s
[INFO] Finished at: Fri Oct 12 01:17:02 EDT 2012
[INFO] Final Memory: 10M/81M
[INFO] ------------------------------------------------------------------------

sitemesh 3.0 alpha 2, I can't get the meta tag value by the content

@OverRide
public String[] selectDecoratorPaths(Content content, WebAppContext context)
throws IOException {

            System.out.println(content.getData().getValue());
            for(ContentProperty cp : content.getExtractedProperties().getChildren()){
                System.out.println(cp.getName()+":"+cp.getValue());
            }
            return new String[]{};
        }

it print that : meta:null , and the data.value can see the meta value
there has something on the html tag resolve

--- it's not a bug, I got it by this method :
content.getExtractedProperties().getChild("meta").getChild("layout").getValue();

thanks very much.

Create a new Release/Milestone

Currently, I am using a Snapshot build that I added to http://repo.springsource.org/simple/ext-snapshot-local/org/sitemesh/sitemesh/3.0.0-SNAPSHOT/

It would be very nice to have something more official.

Cut and Copy tags

Add <sitemesh:cut id="x">../sitemesh:cut and <sitemesh:copy id="y">.../sitemesh:copy tags to allow pages to contain fragments that can be accessed from decorators further down the line. Cut will remove the content, copy will leave it in place.

These would behave like DivExtractingRule and ContentTagExtractingRule - except they will be part of the default tags.

Inquiry - Release 3.0 delivery planned?

With the risk of repeating an old question, is the expected release 3.0 planned, and is there a possible date for this? I don't quite understand, if it has not happened due to possible issues or simply lack of time. As it is already based on maven, a release build itself should not mean much more effort?

The background is, that we would need a stable release to move an application into production, we are not supposed to push SNAPSHOT releases there. It is also definitely not an option to build from source and name it final, as this has to be done by the originator of the software in our opinion.

Could any of you enlighten us on this question? We would appreciate it very much.

Kind regards

Deploy to Maven repositories

Ensure that releases can quickly be pushed to the central Maven repository with little (or zero) interaction or delay.

Also ensure that snapshots from successful continuous integration builds get pushed to a Maven repo (though this does not have to be the central repo).

don't wait while decorated body is completely generated

When decorating a large page body SM3 wait when decorated page body is completely produced, i.e. <sitemesh:write property='body'> tag don't write out decorated body until decorated page is returned completely.

To improve performance in such case it could start streaming chunks of the decorated page before it is completely generated.

Not working at the Wildfly AS

My app working fine in JBoss 7.1.1, but if I update to Wildfly the jsps not be decorated.
The Wildfly will be supported by Sitemesh?

null exception occur when content-type is null

when I use response.sendError(xxx), it flush the header buffer, and response.getContentType will return null.
then,
The constructor of org.sitemesh.webapp.contentfilter.io.HttpContentType deal with this "null" as string, so error happened.

I use response.setStatus as a temporary replacement, but null should be treated
Thank you

here is exception trace for you to know the situation:
java.lang.NullPointerException
at org.sitemesh.webapp.contentfilter.io.HttpContentType.(HttpContentType.java:15)
at org.sitemesh.webapp.contentfilter.HttpServletResponseBuffer.setContentType(HttpServletResponseBuffer.java:159)
at org.sitemesh.webapp.WebAppContext.decorate(WebAppContext.java:131)
at org.sitemesh.BaseSiteMeshContext.decorate(BaseSiteMeshContext.java:39)
at org.sitemesh.webapp.SiteMeshFilter.postProcess(SiteMeshFilter.java:83)
at org.sitemesh.webapp.contentfilter.ContentBufferingFilter.bufferAndPostProcess(ContentBufferingFilter.java:175)
at org.sitemesh.webapp.contentfilter.ContentBufferingFilter.doFilter(ContentBufferingFilter.java:126)
at org.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:120)
at org.sitemesh.config.ConfigurableSiteMeshFilter.doFilter(ConfigurableSiteMeshFilter.java:163)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter.doFilter(StrutsPrepareFilter.java:82)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)

<sitemesh:write property=""> not being parsed inside element attributes

Example1:
<body id='<sitemesh:write property="body.id" />'>
Example2:
<input id='meta.page' type='hidden' value='<sitemesh:write property="meta.page">' />
Example3:
<body id="<sitemesh:write property='body.id' />">

I'm unable to get these to work in sitemesh3 using a .gtpl or .html decorator.

How to get the real request uri when using sitemesh3

When using sitemesh3 to decorate page,the request uri always return the layout page uri.Not the real/original uri.I need the original uri for some purpose,so how to get the real request uri when using sitemesh3

Sitemesh3 POST

after import sitemesh3 into project, all the things work perfectly, only the whole application can not handle POST request.

Alpha2 configuration does not work as expected on v3.0.0 release

As I upgraded to the latest v3.0.0 release, the configuration that used to work on the alpha version stopped working properly: it seems that only the penultimate decorator is applied, regardless of the url. In my case, the main+setup jsp.

<sitemesh>

    <!-- Exclude path from decoration.  -->
    <!--                                -->
    <mapping path="/resources/*" exclue="true"/>

    <!-- Exclude all ajax admin actions -->
    <mapping path="/admin/ajax*" exclue="true" />

    <!-- Exclude all ajax marketing actions -->
    <mapping path="/marketing/ajax*" exclue="true" />

    <!-- Exclude all ajax humanresources actions -->
    <mapping path="/humanresources/ajax*" exclue="true" />

    <!-- Exclude all ajax Store actions -->
    <mapping path="/content/store/ajax*" exclue="true" />

    <!-- Exclude all ajax Lamps actions -->
    <mapping path="/content/lamps/lamp/ajax*" exclue="true" />

    <!-- Exclude all ajax Led actions -->
    <mapping path="/content/lamps/led/ajax*" exclue="true" />

    <!-- Exclude all ajax articoli actions -->
    <mapping path="/content/articoli/ajax*" exclue="true" />

    <!-- Exclude all ajax prodotto actions -->
    <mapping path="/content/prodotto/ajax*" exclue="true" />

    <!-- Exclude all ajax family actions -->
    <mapping path="/content/family/ajax*" exclue="true" />

    <!-- Exclude all ajax project actions -->
    <mapping path="/content/projects/ajax*" exclue="true" />

    <!-- Exclude all ajax customer actions -->
    <mapping path="/customer/ajax*" exclue="true" />


    <!-- Exclusion subFamily -->
    <mapping path="/content/subfamily/ajax-subfamily-rimuovi-pdf.action" exclue="true" />
    <mapping path="/content/subfamily/subfamily-light*.action" exclue="true" />
    <mapping path="/content/subfamily/ajax-product-sorter.action" exclue="true" />
    <mapping path="/content/subfamily/ajax-curvafotometrica-sorter.action" exclue="true" />
    <mapping path="/content/subfamily/ajax-gallery-sorter.action" exclue="true" />

    <!-- Exclusion Family -->
    <mapping path="/content/family/family-designer-getDesigner.action" exclue="true" />

    <!-- Exclusion Struts plugin js -->
    <mapping path="/struts/*" exclue="true" />

    <!--  Prodotto -->
    <mapping path="/content/prodotto/subfamily-accessori-json.action" exclue="true" />
    <mapping path="/content/prodotto/family-designers-json.action" exclue="true" />
    <mapping path="/content/prodotto/prodotto-get-accessories.action" exclue="true" />
    <mapping path="/content/prodotto/prodotto-get-components.action" exclue="true" />
    <mapping path="/content/prodotto/prodotto-remove-*.action" exclue="true" />
    <mapping path="/content/prodotto/prodotto-getform-color*" exclue="true" />

    <!-- Evento/News -->
    <mapping path="/content/eventonews/ajax*" exclue="true" />

    <!-- Preview -->
    <mapping path="/content/preview/ajax*" exclue="true" />


    <!--                                -->
    <!-- Mapping                        -->
    <!--                                -->
    <!-- Map default decorator. This shall be applied to all paths if no other paths match. -->
    <mapping decorator="/decorators/main.jsp"/>


    <mapping>
        <path>/preview/*</path>
        <decorator>/decorators/preview.jsp</decorator>
    </mapping>

    <mapping>
        <path>/marketing/references*</path>
        <decorator>/decorators/marketing-references.jsp</decorator>
        <decorator>/decorators/marketing.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/marketing/*</path>
        <decorator>/decorators/marketing.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/humanresources/*</path>
        <decorator>/decorators/human-resources.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/lamps/*.action</path>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/energylabels/*.action</path>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/family/family*.action</path>
        <decorator>/decorators/cm-p-family.jsp</decorator>
        <decorator>/decorators/cm-prodotti.jsp</decorator>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/subfamily/*.action</path>
        <decorator>/decorators/cm-p-subfamily.jsp</decorator>
        <decorator>/decorators/cm-prodotti.jsp</decorator>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/prodotto/prodotto-preview.action</path>
        <decorator>/decorators/cm-prodotti.jsp</decorator>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/prodotto/prodotto*.action</path>
        <decorator>/decorators/cm-p-subfamily.jsp</decorator>
        <decorator>/decorators/cm-prodotti.jsp</decorator>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/prodotto/prodotti-export*</path>
        <decorator>/decorators/cm-prodotti.jsp</decorator>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/prodotto/prodotti-import*</path>
        <decorator>/decorators/cm-prodotti.jsp</decorator>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/ecommerce/ecommerce.action</path>
        <decorator>/decorators/cm-prodotti.jsp</decorator>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/articoli/articoli.action</path>
        <decorator>/decorators/cm-prodotti.jsp</decorator>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/articoli/articoli-upload.action</path>
        <decorator>/decorators/cm-prodotti.jsp</decorator>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/customer/*</path>
        <decorator>/decorators/customer-support.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/eventonews/*</path>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/designer/*</path>
        <decorator>/decorators/cm-designers.jsp</decorator>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/content/*</path>
        <decorator>/decorators/content-management.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/admin/*</path>
        <decorator>/decorators/administration.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping>
        <path>/setup/*</path>
        <decorator>/decorators/setup.jsp</decorator>
        <decorator>/decorators/main.jsp</decorator>
    </mapping>

    <mapping path="/config-browser/*" decorator="/decorators/config-browser.jsp"/>

</sitemesh>

Sitemesh end development ?

Hi guys, thanks for the nice framework. Recently we decided to use it in out project but, we heard that its development has finished is it true ?

Question

This is not an issue, it is a question. If I have SiteMesh on a server and lets say I am using Java for that SiteMesh, can I develop a C#.net application and Mesh it together. For example I have a header and left nav but the body will be a C#.net application?

ServletPath doesn't return full path

I hit the following issue in SiteMesh 2.x

http://jira.opensymphony.com/browse/SIM-232

I was hoping that SiteMesh3 would fix the issue but it does not, yet. This makes working with Restful Urls almost impossible right now. For example when using Spring MVC, SiteMesh3 sees only the Spring Servlet Url e.g. "/spring/" but not the full path such as: "/spring/users"

Blank response for static HTMLs served by Spring MVC

I'm using Spring MVC, and my static error pages (e.g. 404 error page) are located in a "resources" directory:

  /resources/error-404.html
  /resources/error-403.html
  etc.

Spring lets you define "handlers" for static resources such as this. When a requested URL is not found, in order to return the defined "error-404.html" to the browser, Spring uses a handler class. The handler in question is ResourceHttpRequestHandler.

What's happening is: a blank response is returned to the browser (though the error code is 404 as expected). When i debug SiteMesh's ContentBufferingFilter and HttpServletResponseBuffer, I can see the HTML in the buffer. But it doesn't get back to the browser.

Note: I'm excluding "/resources/*" in my config I.e.

    @Override
    protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
        builder
        ...
        .addExcludedPath("/resources/*") // ignore static resources
        ;
    }

But I don't think that's relevant to this issue, since the original requested URL is very much an included URL.

sitemesh 3.0 alpha 2 can read the meta tag in the body tag

in sitemesh 3.0 alpha 2, when the meta both in the head tag and body tag, I will get the in the body one,
maybe it's some error. I want get this meta tag in the head tag not in the body tag .

the in tag shoud not be process , it's only some html style error.

Asynchronous Servlet Not Supported

Hello, I'm implemented asynchronous servlet using spring which return Callable but the view is not decorated by sitemesh.

Does sitemesh 3 support decorate the view with asynchronous servlet ?

Thanks.

Convert sitemesh website to offline web site

Currently the decorators are being applied by a Servlet container. The entire site is static, so it can be build offline with the SM offline generator.

Benefits:

  • Site can be included as a directory in the SM distribution.
  • Will be served more efficiently by AppEngine's replicated static content service.
  • Offers a lot more options of where we can host it in the future.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.