You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

Assets

Assets are any kind of file that may be downloaded to a client web browser in addition to the dynamically generated HTML.

Assets are most often images, stylesheets, and JavaScript libraries.

Normal assets are stored in the web application's context folder ... stored inside the web application WAR file in the ordinary way.

Tapestry will also make files stored on the classpath, with your Java class files, visible to the web browser.

Assets are exposed to your code as instances of the Asset interface.

Injecting Assets

Components learn about assets via injection. The Inject annotation allows Assets to be injected into components as read-only properties. The path to the resource is specified using the Path annotation.

  @Inject
  @Path("context:images/tapestry_banner.gif")
  private Asset banner;

Assets are located within domains; these domains are identified by the prefix on the Path annotation's value.

If the prefix is omitted, the value will be interpreted as a path relative to the Java class file itself, within the "classpath:" domain. This is often used when creating component libraries, where the assets used by the components are packaged in the JAR with the components themselves.

Unlike elsewhere in Tapestry, case matters. This is because Tapestry is dependenent on the Servlet API and the Java runtime to access the underlying files, and those APIs, unlike Tapestry, are case sensitive. Be aware that some operating systems (such as Windows) are case insenitive, which may mask errors that will be revealed at deployment (if the deployment operating system is case sensitive, such as Linux).

Assets in Templates

Assets can also be referenced directly in templates. Two binding prefixes exist for this: "asset:" and "context:". The "asset:" prefix can obtain assets from the classpath (the default) or from the web context (by specifying the "context:" domain explicitly):

  <img src="${asset:context:image/tapestry_banner.gif}" alt="Banner"/>

This is an example of using a template expansion inside an ordinary element (rather than a component).

Because accessing context assets is so common, the "context:" binding prefix was introduced:

  <img src="${context:image/tapestry_banner.gif}" alt="Banner"/>

Relative Assets

You can use relative paths with domains (if you omit the prefix):

  @Inject
  @Path("../edit.png")
  private Asset icon;

Since you must omit the prefix, this only makes sense for components packaged in a library for reuse.

Symbols For Assets

Symbols inside the annotation value are expanded. This allows you to define a symbol and reference it as part of the path. For example, you could contribute a symbol named "skin.root" as "context:skins/basic" and then reference an asset from within it:

  @Inject
  @Path("${skin.root}/style.css")
  private Asset style;

The use of the ${...} syntax here is a symbol expansion (because it occurs in an annotation in Java code), rather than a template expansion (which occurs only in Tapestry template files).

An override of the skin.root symbol would affect all references to the named asset.

Localization of Assets

Assets are localized; Tapestry will search for a variation of the file appropriate to the effective locale for the request. In the previous example, a German user of the application may see a file named edit_de.png (if such a file exists).

New Asset Domains

If you wish to create new domains for assets, for example to allow assets to be stored on the file system or in a database, you may define a new AssetFactory and contribute it to the AssetSource service configuration.

Asset URLs

Tapestry creates a new URL for assets (whether context or classpath). The URL is of the form /assets/application version number/folder/path.

  • application version number: Defined by symbol tapestry.application-version, the default value is a random hex number.
  • folder: Identifies the library containing the asset, or "ctx" for a context asset, or "stack" (used when combining multiple JavaScript files into a single virtual asset).
  • path: The path below the root package of the library to the specific asset file.

Performance Notes

Assets are expected to be entirely static (not changing while the application is deployed). When Tapestry generates a URL for an asset, either on the classpath or from the context, the URL includes a version number. Further, the asset will get a far future expires header, which will encourage the client browser to cache the asset.

In addition, Tapestry will GZIP compress the content of all assets (if the asset is compressable, and the client supports it).

You should have an explicit application version number for any production application. Client browsers will aggressively cache downloaded assets; they will usually not even send a request to see if the asset has changed once the asset is downloaded the first time. Because of this is is very important that each new deployment of your application get a new version number: this will force existing clients to re-download all files.

  • No labels