Working with assets
Assets are files delivered by your application or by Wisdom. It can be CSS, JavaScript, HTML files or resources such as images.
Wisdom supports three types of assets:
-
Assets packaged with the application, they are placed in the
src/main/resources/assetsdirectory -
Assets served by wisdom but not included in the application, they are placed in the
src/main/assetsdirectory, and copied to thewisdom/assetsdirectory -
Assets packages as webjars.
The list of all available assets is available on /assets (http://localhost:9000/assets). This page is only served
in development mode.
Structuring your assets
We strongly recommend that you use the following conventions to organize your assets:
assets
└ javascripts
└ stylesheets
└ images
How your assets are packaged and served
The assets from src/main/resources/assets are packaged in the application’s jar file (don’t forget it’s an OSGi
bundle).The assets from src/main/assets are placed in the wisdom/assets directory and packaged in the distribution zip
file. Despite this difference, both types of assets are accessible from the /assets/ path.
Let’s see some examples:
src/main/assets/javascripts/script.js ==> /assets/javascripts/script.js src/main/assets/stylesheets/style.css ==> /assets/stylesheets/style.css src/main/resources/assets/javascripts/script.js ==> /assets/javascripts/script.js src/main/resources/assets/stylesheets/style.css ==> /assets/stylesheets/style.css
|
Important
|
When an asset file is present from both sources, the asset from src/main/assets is served. This policy
lets you override internal files with external assets.
|
Wisdom contains a built-in controller to serve the assets. By default, this controller provides caching, ETag, gzip compression and JavaScript minification support.
Etag support
The Assets controller automatically manages ETag HTTP Headers. The ETag value is generated from the file’s last modification date. (If the resource file is embedded into a file, the JAR file’s last modification date is used.)
When a web browser makes a request specifying this Etag, the server can respond with 304 NotModified,
without body. By this method, bandwidth is saved.
You can disable the Etag support by setting http.useETag to false in the application configuration:
http.useETag = false
By default, Etag is enabled.
Cache Control
In addition to the Etag support, Wisdom lets you configure the asset cache time. More preceisely the value set by
Wisdom in the Cache-Control HTTP header. By setting the http.cache_control_max_age configuration property in the
application configuration, you can set the amount of time (in seconds) the browser can keep the resource in its own
cache:
http.cache_control_max_age = 3600
To disable the cache, set this value to 0:
http.cache_control_max_age = 0
This configuration instructs Wisdom to use the no-cache value, forbidding the browser and other proxies to use
caching facilities.
By default, the cache age is set to 3600 seconds.
Gzip support
|
Important
|
Not yet implemented |
Wisdom lets you serve compressed versions of your assets. For a given resource, if a resource with the same name but
using a .gz suffix is found, the Assets controller will serve this one by adding the proper HTTP header:
Content-Encoding: gzip
Of course, Wisdom checks that such encoding is accepted by the browser.
Asset processing
Before being packaged, assets are processed. For example, CoffeeScript files are compiled to JavaScript,
while Less files are compiled to CSS. This processing is done during the build process (and not at runtime).
CoffeeScript processing
CoffeeScript is a little language that compiles into JavaScript. Underneath that awkward
Java-esque patina, JavaScript has always had a gorgeous heart. CoffeeScript is an attempt to expose the good parts of
JavaScript in a simple way. Any .coffee files from your assets are compiled to Javascript automatically. The
source map is also generated. For example, the file src/main/assets/javascripts/some-coffee.coffee:
include::{assetdir}/javascripts/some-coffee.coffee[]
is accessible from /assets/javascripts/some-coffee.js:
include::{assetoutdir}/javascripts/some-coffee.js[]
|
Note
|
In watch mode, the .coffee files are automatically recompiled.
|
The CoffeeScript compilation relies on the original compiler executed on top of the node.js runtime.
Less processing
LESS extends CSS with dynamic behavior such as variables, mixins,
operations and functions. Wisdom automatically compiles any .less files from your assets to CSS. For example,
the file src/main/assets/stylesheets/site.less:
include::{assetdir}/stylesheets/site.less[]
is accessible from /assets/stylesheets/site.css:
include::{assetoutdir}/stylesheets/site.css[]
|
Note
|
In watch mode, the .less files are automatically recompiled.
|
The Less version compilation relies on the original less compiler executed on top of the node.js runtime.
JavaScript Minification
Wisdom integrates Google Closure to check and minify JavaScript files. For
any JavaScript file (even the one generated by the CoffeeScript compiler), a minified version is generated. The
minified file name ends with -min.js. For example, my-script.js will be minified into my-script-min.js.
To use the minified version, add the -min suffix to your script tags in your templates or HTML files.
|
Note
|
Files already minified are not re-minified. |
You can configure the optimization level of the Closure Compiler and the pretty print option from your
pom.xml file:
<configuration>
<googleClosureCompilationLevel>ADVANCED_OPTIMIZATIONS</googleClosureCompilationLevel>
<googleClosurePrettyPrint>true</googleClosurePrettyPrint>
</configuration>
The value of the compilation level can be SIMPLE_OPTIMIZATIONS (default),
WHITESPACE_ONLY or ADVANCED_OPTIMIZATIONS.
The pretty print option lets you configure how the minified file is formatted . Enabling pretty print impacts the final file size but is much more readable.
You can also disable the Google Closure support with:
<configuration>
<skipGoogleClosure>true</skipGoogleClosure>
</configuration>
In watch mode, you can disable Google Closure support with: mvn wisdom:run -DskipGoogleClosure=true