Website Development Best Practices - Enterprise Java Content management system - Hippo CMS

Website Development Best Practices

Introduction

The Essentials setup application implements and promotes a list of best practices for Hippo CMS project development. These best practices help ensure that your Hippo CMS project stays in good shape, and that you avoid certain pitfalls. They also help simplify (speeding up) future upgrades of your project.

Here's a list of Hippo CMS development best practices, in random order.

Don't use static text in rendering templates

Using static text in (WAR-based) rendering templates requires you to re-deploy your project in case you (or your customer) want to change that text. Instead, put static text into resource bundle documents, and include them from there in your rendering templates.

Certain features available through the setup application provide resource bundle documents; they get installed under /administration/labels.

The use of resource bundles is described here.

Check user input against malicious data

All input from external sources, including website users filling in a form, can contain malicious data. Hippo CMS provides tooling to parse such input and guard against abuse / corruption of the project.

All generic HST components provided by Essentials use this tooling. You can find an example usage in org.onehippo.cms7.essentials.components.CommonComponent#cleanupSearchQuery().

It is also strongly recommended to protect against malicious input from CMS users (authors, editors). For this reason all rendering templates bundled with out-of-the-box features apply XML escaping to all CMS content, e.g.:

Freemarker

${document.title?html}

JSP

<c:out value="${requestScope.document.title}"/>

Reuse existing HST components

By reusing existing HST components, you benefit from proven component implementations and save development, debugging and maintenance time. The setup application provides a library with HST components covering the most frequently occurring use cases.

You can customize the behavior of these components to your need by tuning the component parameters, or by making your custom component extend from one of the library components.

Make your HST components accessible

If you develop custom components, consider registering them as Channel Editor catalog components. Like that, you can leverage the Channel Editor's component parameter dialog capability such that you (or the web master) can fine-tune the component's behavior through a user-friendly UI. Also, this will allow you to make use of the Switch Templates feature. For this to work, be sure to annotate your component with an appropriate parameters info interface, and set up your HST configuration such that the component resides inside an HST container.

Many features of the setup application install catalog components into the essentials catalog. They also install page configurations with containers to drop these components.

Make catalog components easily recognizable

In the Channel Editor, when you first drop a catalog component into a container, you often require some basic configuration before the component can render useful content. Before that, components typically render nothing.

Catalog components installed by the setup application provide a piece of mark-up which only shows inside the Channel Editor, such that it gets clear which (unconfigured) component is available for configuration where.

When creating a custom catalog component yourself, you may want to have a look at how the essentials catalog component rendering templates achieve that. Assuming that you use  web files-based Freemarker templates (rather than WAR-based JSPs), you can find examples in your project's /repository-data/webfiles/src/main/resources/site/freemarker/hstdefault directory.

Limit your queries

When determining what content to show, you will regularly want to execute queries on your set of content. These queries consume resources, and you best limit the amount of resources consumed by a query by specifying appropriate query limits.

The generic HST components provided by he setup application implement the use of such limits by calling the org.hippoecm.hst.content.beans.query.HstQuery#setLimit() function.

Likewise, if you set up a content tree for faceted navigation, make sure you apply appropriate limits.

Use iterators rather than fetching lists

In your HST component or content bean code, you will regularly find a need to iterate over a set of data. For best performance, try using the provided iterators rather than fetching the set of data in a non-native format (i.e. in a format different from the one the set of data is available in).

The generic HST components and content beans provided by the setup application use these iterators wherever possible.

Provide appropriate page-not-found support

There are two use-cases where your site can conclude that there's no content to show: Either (1) the requested URL is not mapped to any sitemap item, or (2) the matching sitemap item is not associated with any content. In the first case, the best practice is to set up a root-level catch-all sitemap item, which renders a page-not-found page. In the second case, the HST components rendering the site should, upon determining that there is no content, redirect the browser to an appropriate page-not-found page.

The setup application implements this best practice by installing a root-level _any_ catch-all sitemap item, and the setup application's base HST component implements the org.onehippo.cms7.essentials.components.CommonComponent#setContentBeanWith404() function as an example how to implement the second case.

Stay up to date with Hippo CMS maintenance releases

BloomReach regularly creates maintenance releases for Hippo CMS, fixing known issues and providing handy new features. After you've created your Hippo CMS project, regularly check for new maintenance releases to make sure you get the most benefit from them.

The setup application is kept up-to-date with the latest maintenance releases by means of new archetype versions. Check here for the recommended archetype version at any time.

Website Development Best Practices

Introduction

The Essentials setup application implements and promotes a list of best practices for Hippo CMS project development. These best practices help ensure that your Hippo CMS project stays in good shape, and that you avoid certain pitfalls. They also help simplify (speeding up) future upgrades of your project.

Here's a list of Hippo CMS development best practices, in random order.

Don't use static text in rendering templates

Using static text in (WAR-based) rendering templates requires you to re-deploy your project in case you (or your customer) want to change that text. Instead, put static text into resource bundle documents, and include them from there in your rendering templates.

Certain features available through the setup application provide resource bundle documents; they get installed under /administration/labels.

The use of resource bundles is described here.

Check user input against malicious data

All input from external sources, including website users filling in a form, can contain malicious data. Hippo CMS provides tooling to parse such input and guard against abuse / corruption of the project.

All generic HST components provided by Essentials use this tooling. You can find an example usage in org.onehippo.cms7.essentials.components.CommonComponent#cleanupSearchQuery().

It is also strongly recommended to protect against malicious input from CMS users (authors, editors). For this reason all rendering templates bundled with out-of-the-box features apply XML escaping to all CMS content, e.g.:

Freemarker

${document.title?html}

JSP

<c:out value="${requestScope.document.title}"/>

Reuse existing HST components

By reusing existing HST components, you benefit from proven component implementations and save development, debugging and maintenance time. The setup application provides a library with HST components covering the most frequently occurring use cases.

You can customize the behavior of these components to your need by tuning the component parameters, or by making your custom component extend from one of the library components.

Make your HST components accessible

If you develop custom components, consider registering them as Channel Editor catalog components. Like that, you can leverage the Channel Editor's component parameter dialog capability such that you (or the web master) can fine-tune the component's behavior through a user-friendly UI. Also, this will allow you to make use of the Switch Templates feature. For this to work, be sure to annotate your component with an appropriate parameters info interface, and set up your HST configuration such that the component resides inside an HST container.

Many features of the setup application install catalog components into the essentials catalog. They also install page configurations with containers to drop these components.

Make catalog components easily recognizable

In the Channel Editor, when you first drop a catalog component into a container, you often require some basic configuration before the component can render useful content. Before that, components typically render nothing.

Catalog components installed by the setup application provide a piece of mark-up which only shows inside the Channel Editor, such that it gets clear which (unconfigured) component is available for configuration where.

When creating a custom catalog component yourself, you may want to have a look at how the essentials catalog component rendering templates achieve that. Assuming that you use  web files-based Freemarker templates (rather than WAR-based JSPs), you can find examples in your project's /repository-data/webfiles/src/main/resources/site/freemarker/hstdefault directory.

Limit your queries

When determining what content to show, you will regularly want to execute queries on your set of content. These queries consume resources, and you best limit the amount of resources consumed by a query by specifying appropriate query limits.

The generic HST components provided by he setup application implement the use of such limits by calling the org.hippoecm.hst.content.beans.query.HstQuery#setLimit() function.

Likewise, if you set up a content tree for faceted navigation, make sure you apply appropriate limits.

Use iterators rather than fetching lists

In your HST component or content bean code, you will regularly find a need to iterate over a set of data. For best performance, try using the provided iterators rather than fetching the set of data in a non-native format (i.e. in a format different from the one the set of data is available in).

The generic HST components and content beans provided by the setup application use these iterators wherever possible.

Provide appropriate page-not-found support

There are two use-cases where your site can conclude that there's no content to show: Either (1) the requested URL is not mapped to any sitemap item, or (2) the matching sitemap item is not associated with any content. In the first case, the best practice is to set up a root-level catch-all sitemap item, which renders a page-not-found page. In the second case, the HST components rendering the site should, upon determining that there is no content, redirect the browser to an appropriate page-not-found page.

The setup application implements this best practice by installing a root-level _any_ catch-all sitemap item, and the setup application's base HST component implements the org.onehippo.cms7.essentials.components.CommonComponent#setContentBeanWith404() function as an example how to implement the second case.

Stay up to date with Hippo CMS maintenance releases

BloomReach regularly creates maintenance releases for Hippo CMS, fixing known issues and providing handy new features. After you've created your Hippo CMS project, regularly check for new maintenance releases to make sure you get the most benefit from them.

The setup application is kept up-to-date with the latest maintenance releases by means of new archetype versions. Check here for the recommended archetype version at any time.