Extend CommonComponent with a Do-Before-Render Extension
Overview
This page describes how to inject custom logic into the CommonComponent class so that all components extending CommonComponent execute this logic before rendering.
When to Use
Use this approach when you need all components that extend CommonComponent to perform a specific action before rendering. This is common when you want to make shared data available to rendering templates.
Background
All standard components provided by Essentials inherit from the abstract class org.onehippo.cms7.essentials.components.CommonComponent. The CommonComponent class exposes an extension point in its doBeforeRender method. You can use this extension point to run additional code before rendering.
The extension point uses the interface org.onehippo.cms7.essentials.components.ext.DoBeforeRenderExtension. By default, the implementation is a no-operation class: org.onehippo.cms7.essentials.components.ext.NoopDoBeforeRenderExtension.
Example
Scenario
This example uses a Bloomreach Content project created from the Maven Archetype with the Blog feature added.
The Blog feature includes a "blog categories" key-value list. This list is managed as a document in the CMS and is accessible in the delivery tier through a ValueListManager configured as a Spring bean. The setup application provides a UI for creating this configuration. The generated configuration is located at:
site/components/src/main/resources/META-INF/hst-assembly/overrides/valueListManager.xml
<bean id="org.onehippo.forge.selection.hst.manager.ValueListManager" class="org.onehippo.forge.selection.hst.manager.DefaultValueListManager"> <constructor-arg> <map> <!--<entry key="name" value="/absolute/repository/path"/>--> <entry key="categories" value="/content/documents/myproject/blog/blog-categories"/> </map> </constructor-arg> </bean>
To make the categories key-value list available as a request attribute in any rendering template, implement a DoBeforeRenderExtension. This extension will run for every component before rendering.
Note:
ADoBeforeRenderExtensionruns for every component that extendsCommonComponent. If the extension retrieves data from external sources, it may impact performance. In this example, the key-value list is cached in memory. For other use cases, consider caching data in theHstRequestContextto avoid repeated lookups.
Prerequisites
- A Bloomreach Content project with the Blog feature enabled.
- The
ValueListManagerSpring bean configured as shown above.
Implementation Steps
1. Implement the DoBeforeRenderExtension Interface
Create a class org.example.extensions.CategoriesDoBeforeRenderExtension that implements DoBeforeRenderExtension.
In the execute method, retrieve the ValueListManager bean, obtain the categories value list, and store it as a request attribute named categories.
File: site/components/src/main/java/org/example/extensions/CategoriesDoBeforeRenderExtension.java
package org.example.extensions; import org.hippoecm.hst.content.beans.standard.HippoBean; import org.hippoecm.hst.core.component.HstRequest; import org.hippoecm.hst.core.component.HstResponse; import org.hippoecm.hst.site.HstServices; import org.onehippo.cms7.essentials.components.CommonComponent; import org.onehippo.cms7.essentials.components.ext.DoBeforeRenderExtension; import org.onehippo.forge.selection.hst.contentbean.ValueList; import org.onehippo.forge.selection.hst.manager.ValueListManager; import org.onehippo.forge.selection.hst.util.SelectionUtil; public class CategoriesDoBeforeRenderExtension implements DoBeforeRenderExtension { @Override public void execute(final CommonComponent component, final HstRequest request, final HstResponse response) { ValueListManager valueListManager = HstServices.getComponentManager().getComponent(ValueListManager.class.getName()); HippoBean siteContentBaseBean = request.getRequestContext().getSiteContentBaseBean(); ValueList categoriesValueList = valueListManager.getValueList(siteContentBaseBean, "categories"); if (categoriesValueList != null) { request.setAttribute("categories", SelectionUtil.valueListAsMap(categoriesValueList)); } } }
2. Register the Extension as a Spring Bean
Update the Spring configuration to replace the default NoopDoBeforeRenderExtension with your custom implementation.
File: site/components/src/main/resources/META-INF/hst-assembly/overrides/hippo-essentials-spring.xml
<bean id="org.onehippo.cms7.essentials.components.ext.DoBeforeRenderExtension" class="org.example.extensions.CategoriesDoBeforeRenderExtension"/>
3. Access the Key-Value List in a Template
After configuration, any component that extends CommonComponent will have a request attribute named categories (a java.util.Map) available to its rendering template.
For example, to display a blog post's categories on the blog overview page, add the following to the blog-list.ftl template:
File: repository-data/webfiles/src/main/resources/site/freemarker/hstdefault/blog/blog-list.ftl
<ul> <#list item.categories as category> <li>${categories[category]}</li> </#list> </ul>
Verification
- Deploy your changes.
- Access a page that uses a component extending
CommonComponent. - Confirm that the
categoriesrequest attribute is available in the template and renders as expected.