Use Web Files

Introduction

Goal

Refer to web files in templates, and store Freemarker templates as web files.

Background

Web Files are static web resources (such as CSS and Javascript files, and Freemarker templates) which are stored in the content repository. This page explains how to use web files in your Hippo project: where to store web files, how to reference web files in a template, and how to store templates as web files.

Set Up Project for Web Files

Projects created from the Maven archetype are already set up for web files.

Other (older) projects can be upgraded to web files as part of the upgrade to Hippo 10.

The default configuration will be fine in most cases, however if you have specific needs see the following pages:

Web Files Location

Each web application can make use of its own web file bundle. The name of the used bundle is the same as the web application context (e.g. "site" for the the site.war application). A web file bundle consists of files and directories. Directories can be used to organize web files hierarchically. Web files are identified by a path relative to the bundle’s root directory (e.g. /css/style.css).

In a standard project the site's web file bundle is stored in the repository-data-webfiles module in the src/main/resources/site folder:

repository-data/webfiles/src/main/resources/site

The web files are organized by type in corresponding subfolders of site, such as css, js, fonts and freemarker.

When starting the application the web files are bootstrapped in the content repository at /webfiles/site.

In a local development environment, modifying web files on the file system will automatically trigger synchronization of the modified web files in the repository and reload affected pages that are open in a web browser.

The repository-data-webfiles module and the web files inside it should be kept in a version control system along with all the other project source files.

Refer to Web Files in Templates

First make sure the HST tag library is available. Typically this is done through including a generic "imports" template:

Freemarker

<#include "../include/imports.ftl">

JSP

<%@ include file="/WEB-INF/jsp/include/imports.jsp" %>

Then use the hst:webfile tag to refer to any resource in the web file bundle:

Freemarker

<@hst.webfile var="link" path="/js/script.js" />
<script src="${link}" />

JSP

<hst:webfile var="link" path="/js/script.js" />
<script src="${link}" />

This example will result in the following rendered markup:

<script src="/webfiles/<anti-cache>/js/script.js" />

The <anti-cache> URL part is generated automatically whenever something changes in the bundle. It assures that browsers do not use older, cached versions of web files while still caching all web files as long as they have not changed. All web files get an 'Expires' header of one year (aka caching 'forever').

If you require access to stable web file URLs, for example because you have some server side NodeJs application that wants to fetch a web file by a stable URL, you can enable this as described on Web Files Stable URLs.

Store Freemarker Templates as Web Files

Freemarker templates can be stored as web files. The file names of Freemarker templates must end with " .ftl". For example, the main layout of the web pages in a project could be rendered by the web file template /ftl/layout/webpage.ftl. That template would be stored in the following file system location in a project:

+ repository-data
  + webfiles
    + src
      + main
        + resources
          + site
            + ftl
              +layout
                + webpage.ftl

An template configuration node can refer to a Freemarker web file via a property  hst:renderpath value that starts with “ webfile:” followed by the web file path. For example:

+ hst:hst
  + hst:configurations
    + myproject
      + hst:templates
        + layout.webpage
          - hst:renderpath = webfile:/ftl/layout/webpage.ftl

The render path  webfile:/ftl/layout/webpage.ftl is actually a shorthand for  jcr:/webfiles/site/ftl/layout/webpage.ftl. The “ webfile:” notation is preferred though, since it automatically resolves the exact storage location and application context name.

Live Reload: Auto-Reload Browsers When Web Files Change

During local development, changing a web file will automatically reload all browser pages that are rendering a Hippo site. Magic!

Auto-reload can be turned on and off with a configuration property:

/hippo:configuration/hippo:modules/autoreload/hippo:moduleconfig
  - enabled = true

Changes to this property are picked up immediately.

Is It Active?

The status of auto-reload is logged on the command line when Tomcat is started and whenever it is turned on or off. For example:

[INFO] [talledLocalContainer] 09:44:53 Automatic reload of browsers is enabled

Auto-reload also logs some debug messages in the JavaScript console of the browser. For example:

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/library/concepts/web-resources/autoreload-javascript-console-message.png

Auto-reload is not supported when using a reverse proxy such as described here for Apache HTTP Server.
Do Not Use Auto-Reload in Production
The auto-reload functionality is only available when the file hippo-service-autoreload-<version>.jar is present in Tomcat's shared/lib directory. During local development the Cargo plugin configuration in the Hippo CMS release pom takes care of this. On production, the auto-reload JAR file should not be present in any of Tomcat's and web application's library folders, otherwise each visitor will try to setup a WebSocket connection to the server.

Technical Background

Auto-reloading only works in browsers that support WebSockets. Each browser connects to a WebSocket server running in Tomcat, and reloads the current page whenever the server tells it to.

When Tomcat is stopped, each auto-reloading browser will try to reconnect for 10 minutes. If within that timeframe Tomcat is started again, each browser will reconnect to the server and continue auto-reloading. After 10 minutes the auto-reload script gives up. Each browser will then have to be refreshed once manually to pickup changes again.

Hippo's delivery tier automatically adds the auto-reload script to the head contributions of the site. Auto-reload therefore requires an <hst:headContributions> tag in the template of the top-level component of a page in order to work.