Excerpt |
---|
|
How to create a library of your custom components |
Creating Component Libraries
...
Tapestry doesn't mandate that you use any build system, but we'll assume for the moment that you are using Maven 2. In that case, you'll have a pom.xml file something like the following:
Code Block |
---|
language | xmlXML |
---|
title | pom.xml | XML |
---|
|
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>happylib</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>happylib Tapestry 5 Library</name>
<dependencies>
<dependency>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-core</artifactId>
<version>${tapestry-release-version}</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.1</version>
<classifier>jdk15</classifier>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<optimize>true</optimize>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Tapestry-Module-Classes>org.example.happylib.services.HappyModule</Tapestry-Module-Classes>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>codehaus.snapshots</id>
<url>http://snapshots.repository.codehaus.org</url>
</repository>
<repository>
<id>OpenQA_Release</id>
<name>OpenQA Release Repository</name>
<url>http://archiva.openqa.org/repository/releases/</url>
</repository>
</repositories>
<properties>
<tapestry-release-version>5.2.0</tapestry-release-version>
</properties>
</project>
|
...
Our component is very simple:
Code Block |
---|
language | java |
---|
title | HappyIcon.java | java |
---|
|
package org.example.happylib.components;
import org.apache.tapestry5.Asset;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.Path;
import org.apache.tapestry5.ioc.annotations.Inject;
public class HappyIcon
{
@Inject
@Path("happy.jpg")
private Asset happyIcon;
boolean beginRender(MarkupWriter writer)
{
writer.element("img", "src", happyIcon);
writer.end();
return false;
}
}
|
...
The above naming is somewhat clumsy, and can be improved by introducing an additional namespace into the template:
Code Block |
---|
|
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"
xmlns:h="tapestry-library:happy">
...
<h:icon/>
...
</html>
|
...
At application startup, Tapestry will read the library module along with all other modules and configure the ComponentClassResolver service using information in the module:
Code Block |
---|
language | java |
---|
title | HappyModule.java | java |
---|
|
package org.example.happylib.services;
import org.apache.tapestry5.ioc.Configuration;
import org.apache.tapestry5.services.LibraryMapping;
public class HappyModule
{
public static void contributeComponentClassResolver(Configuration<LibraryMapping> configuration)
{
configuration.add(new LibraryMapping("happy", "org.example.happylib"));
}
}
|
...
For Tapestry to load your module at application startup, it is necessary to put an entry in the JAR manifest. This is taken care of in the pom.xml above:
Code Block |
---|
language | xml |
---|
title | pom.xml (partial)xml |
---|
|
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Tapestry-Module-Classes>org.example.happylib.services.HappyModule</Tapestry-Module-Classes>
</manifestEntries>
</archive>
</configuration>
</plugin>
|
...
As of Tapestry 5.2, a new step is needed: extending access for the assets. This is accomplished in your library's module class, HappyModule:
Code Block |
---|
|
public static void contributeRegexAuthorizer(Configuration<String> configuration)
{
configuration.add("^org/example/happylib/.*\\.jpg$");
}
|
...
To handle this problem in Tapestry 5.1 and earlier, you should map your library assets to a versioned folder. This can be accomplished using another contribution from the HappyModule, this time to the ClasspathAssetAliasManager service whose configuration maps a virtual folder underneath /assets to a package:
Code Block |
---|
|
public static void contributeClasspathAssetAliasManager(MappedConfiguration<String, String> configuration)
{
configuration.add("happylib/1.0", "org/example/happylib");
}
|
...