Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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 ... there's no need to unpackage the happy.jpg file. This works for any asset file stored under the libraries librarie's root package.

This component renders out an img tag for the icon.

...

In our example, we'll use "happy" as the folder name. That means the application will include the HappyIcon component in the template as:

  • <t:happy.happyicon>happyicon/> or <t:happy.icon>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.

The above naming is somewhat clumsy, and can be improved by introducing an additional namespace into the template:

...

Tapestry needs to know where to search for your component class. This is accomplished in your library's IoC module class, by making a contribution to the ComponentClassResolver 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 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 doesn't replace Tapestry's 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).

Step 4: Configure the module to autoload

For Tapestry to autoload 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
xml
xml
titlepom.xml (partial)
      <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>

Conclusion

That's 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.

...

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 librarie's 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.