[CONF] Apache Tapestry Component Libraries
Bob Harner edited the page: Component Libraries Comment: fixed language param of code macro Wiki Markup {scrollbar} Excerpt hidden true 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 XML title
[CONF] Apache Tapestry Component Libraries
Component Libraries Page edited by Bob Harner Comment: More smoothly integrated the paragraphs on 5.2's automatic asset version mapping Changes (4) ... The image file here would exposed to the web browser via the URL /happyapp/assets/org/example/happylib/components/happy.jpg (this assumes that the application was deployed as happyapp.war). Tapestry uses a far-future expiration date for classpath assets; this allows browsers to aggressively cache the file, but in Tapestry 5.1 and earlier this causes a problem should when a later version of the library changes the file. This is discussed in detail in [Yahoos Performance Best Practices|http://developer.yahoo.com/performance/rules.html#expires]. 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} ... With this in place, and the library and applications rebuilt and redeployed, the URL for happy.jpg becomes /happyapp/assets/happylib/1.0/components/happy.jpg. This is shorter, but also incorporates a version number (1.0) that can be changed in a later release. {since:since=5.2} In version 5.2 and later, Tapestry automatically creates a mapping for assets inside your JAR. In the above example, the icon image will be exposed as {{/assets/}}{_}application version{_}{{/happy/components/happy.jpg}} (the application version number is incorporated into the URL). The happy portion is a virtual folder that maps to the librarys root package (as folder {{org/example/happylib}} on the Java classpath). The application version is a configurable value. {since} h2. Conclusion Thats it\! Autoloading plus the virtual folders for components and for assets takes care of all the issues related to components. Just build your JARs, setup the JAR Manifest, and drop them into your applications. {since:since=5.2}{since} h2. A note about Assets Tapestry automatically creates a mapping for assets inside your JAR. In the above example, the icon image will be exposed as {{/assets/}}{_}application version{_}{{/happy/components/happy.jpg}} (the application version number is incorporated into the URL). The happy portion is a virtual folder that maps to the librarys root package (as folder {{org/example/happylib}} on the Java classpath). The application version is a configurable value. In Tapestry 5.1 and earlier, it was necessary to explicitly create a mapping, via a contribution to the ClasspathAssetAliasManager service, to expose library assets. This is no longer necessary in Tapestry 5.2. Full Content Supporting Informal ParametersCookbookSwitching Cases Creating Component Libraries Nearly every Tapestry application includes a least a couple of custom components, specific to the application. What's exciting about Tapestry is how easy it is to package components for reuse across many applications ... and the fact that applications using a component library need no special configuration. A Tapestry component library consists of components (and optionally mixins, pages and component base classes). In addition, a component library will have a module that can define new services (needed by the components) or configure other services present in Tapestry. Finally, components can be packaged with assets: resources such as images, stylesheets and _javascript_ libraries that need to be provided to the client web browser. We're going to create a somewhat insipid component that displays a large happy face icon. 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: pom.xml project modelVersion4.0.0/modelVersion groupIdorg.example/groupId artifactIdhappylib/artifactId version1.0-SNAPSHOT/version packagingjar/packaging namehappylib Tapestry 5 Library/name dependencies dependency groupIdorg.apache.tapestry/groupId artifactIdtapestry-core/artifactId version${tapestry-release-version}/version /dependency dependency groupIdorg.testng/groupId artifactIdtestng/artifactId version5.1/version classifierjdk15/classifier scopetest/scope /dependency /dependencies build plugins plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-compiler-plugin/artifactId configuration source1.5/source
[CONF] Apache Tapestry Component Libraries
Component Libraries Page edited by Howard M. Lewis Ship Changes (10) ... {code} HappyIcon appears inside the components sub-package. The happyIcon field is injected with the the Asset for the file {{happy.jpg}}. The path specified with the @Path annotation is relative to the {{HappyIcon.class}} file; it should be stored in the project under {{src/main/resources/org/example/happylib/components}}. Tapestry ensures that the {{happy.jpg}} asset can be accessed from the client web browser; the src attribute of the img tag will be a URL that directly accesses the image file ... theres no need to unpackage the {{happy.jpg}} file. This works for any asset file stored under the libraries root package. This component renders out an img tag for the icon. ... In our example, well use happy as the folder name. That means the application will include the HappyIcon component in the template as: * {{t:happy.happyicon}} or {{t:happy.icon}} * {{img t:type=happy.happyicon}} or {{img t:type=happy.icon}} * {{t:happy.happyicon/}} or {{t:happy.icon/}} * {{img t:type=happy.happyicon/}} or {{img t:type=happy/icon/}} Why icon vs. happyicon? Tapestry notices that the folder name, happy is a prefix or suffix of the class name (HappyIcon) and creates an alias that strips off the prefix (or suffix). To Tapestry, they are completely identical: two different aliases for the same component class name. ... h2. Step 3: Configure the library Tapestry needs to know where to search for your component class. This is accomplished in your librarys IoC module class, by making a _contribution_ to the ComponentClassResolver [service configuration|../../tapestry-ioc/configuration.html]. service configuration. At application startup, Tapestry will read the library module along with all other modules and configure the ComponentClassResolver service using information in the module: ... This module class is also where you would define new services that can be accessed by your components (or other parts of the application). *Note:* it {note}It is possible to add a mapping for core. core is the core library for Tapestry components; all the built-in Tapestry components (TextField, BeanEditForm, Grid, etc.) are actually in the core library. All Tapestry does is search inside the core library when it does find a component in the application. Contributing an additional package as core simply extends the number of packages searched for core components (it doesnt replace Tapestrys default package, org.apache.tapestry5.corelib). Adding to core is sometimes reasonable, if there is virtually no chance of a naming conflict (via different modules contributing packages to core with conflicting class names). {note} h2. Step 4: Configure the module to autoload For Tapestry to [autoload|../../tapestry-ioc/autoload.html] 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:xml|title=pom.xml (partial)} ... /configuration/plugin {code} ... h2. A note about Assets Tapestry automatically creates a mapping for assets inside your JAR. In the above example, the icon image will be exposed as /assets/_application version_/happy/components/happy.jpg {{/assets/}}_application version_{{/happy/components/happy.jpg}} (the application version number is incorporated into the URL). The happy portion is a virtual folder that maps to the libraries root package (as folder org/example/happylib {{org/example/happylib}} on the Java classpath). The application version is [a a configurable value|../guide/conf.html]. value. In Tapestry 5.1 and earlier, it was necessary to explicitly create a mapping, via a contribution to the ClasspathAssetAliasManager service, to expose library assets. This is no longer necessary in Tapestry 5.2. Full Content Creating Component Libraries Nearly every Tapestry application includes a least a couple of custom components, specific to the application. What's exciting about Tapestry is how easy it is to package components for reuse across many applications ... and the fact that applications using a component library need no special configuration. A Tapestry component library consists of components (as well as component base class, pages and mixins). In addition, a component library will have a module that can define new services (needed by the components) or configure