- ExtensionlessURLs

Available since OmniFaces 1.0

FacesViews is a mechanism to use SEO-friendly extensionless URLs in a Faces application without the need to enlist individual Facelet source files in some configuration file.

By default, all URLs generated by ViewHandler.getActionURL(FacesContext, String), which is used by among others <h:form>, <h:link>, <h:button> and all extended tags, will also be extensionless. And, URLs with an extension will be 301-redirected to the extensionless one.

Usage

Zero configuration

Put Facelets source files into /WEB-INF/faces-views directory. All Facelets files in this special directory will be automatically scanned as extensionless URLs.

Minimal configuration

Below is the minimal web.xml configuration to make all Facelets source files found in the root folder and all subdirectories of the public web content (excluding /WEB-INF, /META-INF and /resources) available as extensionless URLs:

<context-param>
    <param-name>org.omnifaces.FACES_VIEWS_SCAN_PATHS</param-name>
    <param-value>/*.xhtml</param-value>
</context-param>

The path pattern /*.xhtml basically means that all files with the .xhtml extension from the directory / must be scanned, including all sub directories. In case you want to scan only .xhtml files in the directory /foo, then use path pattern of /foo/*.xhtml instead. In case you want to scan all files in the directory /foo, then use path pattern of /foo. You can specify multiple values separated by a comma.

MultiViews configuration

Enabling MultiViews is a matter of suffixing the path pattern with /*. The support was added in OmniFaces 2.5. Below is the web.xml configuration which extends the above minimal configuration with MultiViews support:

<context-param>
    <param-name>org.omnifaces.FACES_VIEWS_SCAN_PATHS</param-name>
    <param-value>/*.xhtml/*</param-value>
</context-param>

On an example URL of https://example.com/context/foo/bar/baz when neither /foo/bar/baz.xhtml nor /foo/bar.xhtml exist, but /foo.xhtml does exist, then the request will forward to /foo.xhtml and make the values bar and baz available as injectable path parameters via @Param in the managed bean associated with /foo.xhtml.

@Inject @Param(pathIndex=0)
private String bar;

@Inject @Param(pathIndex=1)
private String baz;

Advanced configuration

See package documentation for configuration settings as to mapping, filtering and forwarding behavior.

PrettyFaces

Note that there is some overlap between this feature and PrettyFaces. The difference is that FacesViews has a focus on zero- or very minimal config, where PrettyFaces has a focus on very powerful mapping mechanisms, which of course need some level of configuration. As such FacesViews will only focus on auto discovering views and mapping them to both .xhtml and to no-extension without needing to explicitly declare the FacesServlet in web.xml.

Specifically, FacesViews will thus not become a general URL rewriting tool (e.g. one that maps path segments to parameters, or that totally changes the name of the URL). For this the user is advised to look at the aforementioned PrettyFaces.

Demo

The showcase application runs on FacesViews and is thus an implicit demo. An extra demo is given below:

Navigate to FacesViews pages without an extension: viewsdemo

Demo source code
<p>
    The showcase application runs on FacesViews and is thus an implicit demo. An extra demo
    is given below:
</p>
<p>
    Navigate to FacesViews pages without an extension: 
    <a href="#{request.contextPath}/viewsdemo">viewsdemo</a>
</p>