Sunday, May 3, 2020

OmniFaces 3.6 adds manifest.json generator, o:scriptParam, and o:pathParam

OmniFaces 3.6 has been released!

Next to a bunch of utility methods, this version adds a WebAppManifestResourceHandler which autogenerates the manifest.json based on properties of a CDI bean, the <o:scriptParam> which allows you to set evaluated JavaScript results in a managed bean, and a <o:pathParam> which can be used in UIOutcomeTarget components (such as <h:link>) to populate desired path parameters for pages covered by MultiViews.

You can find the complete list of additions, changes and fixes at What's new in OmniFaces 3.6? list in showcase. One of most important changes is that the of:formatDateXxx() functions now also support java.time.Temporal instances.


Non-Maven users: download OmniFaces 3.6.1 JAR and drop it in /WEB-INF/lib the usual way, replacing the older version if any.

Maven users: use <version>3.6.1</version>.



This resource handler takes care of automatically generating a manifest.json file, which is one of the minimum requirements for a Progressive Web Application (PWA). All you need to do is to extend from the org.omnifaces.resourcehandler.WebAppManifest class, implement and override the desired getter methods, put a CDI scope annotation on it such as @ApplicationScoped, and finally reference it in your Facelet template exactly as below:

<link rel="manifest" href="#{resource['omnifaces:manifest.json']}" />

And you're done! See also the showcase.


This new little brother of <hashParam> is capable of running some JavaScript code on page load, collect its results and populate the managed bean with them. The @PostScriptParam annotation can be used to invoke a method after the script params have been populated.

For example,

    <o:scriptParam script="new Date().timeZoneOffset()" value="#{bean.clientTimeZoneOffset}" />
private Integer clientTimeZoneOffset; // +getter +setter

public void initScriptParams() {
    System.out.println("The client time zone offset is: " + clientTimeZoneOffset);

See also the live demo.


In case you're using MultiViews, i.e. when you have for example a /users.xhtml page which can be opened as /users/42/john-doe, then you can use the new <o:pathParam> to safely URI-encode the path parameters into any link to /users.xhtml.

For example,

<ui:repeat value="#{bean.users}" var="user">
    <h:link outcome="/users" value="#{}">
        <o:pathParam value="#{}">
        <o:pathParam value="#{user.slug}">

See also the showcase.

How about OmniFaces 2.x and 1.1x?

The 2.x got the same bugfixes as 3.6 and has been released as 2.7.5. This version is for JSF 2.2 users with CDI. In case you've already migrated to JSF 2.3, use 3.x instead.

The 1.1x is basically already since 2.5 in maintenance mode. I.e. only critical bugfix versions will be released. It's currently still at 1.14.1 (May 2017), featuring the same features as OmniFaces 2.4, but without any JSF 2.2 and CDI things and therefore compatible with CDI-less JSF 2.0/2.1.