Customize Link Processing

Overview

This page describes how to customize internal link processing in the Bloomreach Content delivery tier.

When to Use

Customize link processing when you need to modify how internal links are generated or resolved, such as changing URL structures that do not match your repository organization or sitemap configuration.

Background

Bloomreach Content maps documents to pages using a sitemap. Internal links are created and resolved based on this mapping. The link creation and resolution process can be extended using the HstLinkProcessor interface. Implement this interface to apply custom logic before or after link processing.

HstLinkProcessor

The org.hippoecm.hst.core.linking.HstLinkProcessor interface provides two extension points:

  • HstLink postProcess(HstLink link)
    Invoked after a link is created by org.hippoecm.hst.core.linking.HstLinkCreator.
  • HstLink preProcess(HstLink link)
    Invoked before a link is matched by org.hippoecm.hst.core.request.HstSiteMapMatcher.

The delivery tier uses a chain of link processors. You can add multiple custom processors to this chain using Spring configuration.

Important:
Implementations of HstLinkProcessor must be thread-safe. Do not store state in member variables.

Example

Scenario

Suppose you have a project created from the Bloomreach Content Maven archetype with the Simple Content feature added.

Documents of type myproject:contentdocument are stored in /content/documents/myproject/content.

The following sitemap configuration maps these documents to URLs and page templates:

/hst:myproject/hst:configurations/myproject/hst:sitemap: /content: jcr:primaryType: hst:sitemapitem hst:componentconfigurationid: hst:pages/contentlist hst:relativecontentpath: content /_any_.html: jcr:primaryType: hst:sitemapitem hst:componentconfigurationid: hst:pages/contentpage hst:relativecontentpath: ${parent}/${1}

A document at /content/documents/myproject/content/sample-document is available at http://localhost:8080/site/content/sample-document.html.

Now, if you organize documents in subfolders based on the first character of the document name, your repository structure might look like:

/content/documents/myproject: /content: jcr:primaryType: hippostd:folder /a: jcr:primaryType: hippostd:folder /about-hippo: jcr:primaryType: hippo:handle /archetype: jcr:primaryType: hippo:handle /b: jcr:primaryType: hippostd:folder /best-practices: jcr:primaryType: hippo:handle /big-hippo: jcr:primaryType: hippo:handle /c: jcr:primaryType: hippostd:folder /code-formatting: jcr:primaryType: hippo:handle /create-project: jcr:primaryType: hippo:handle

This structure results in URLs such as http://localhost:8080/site/content/a/about-bloomreach.html and http://localhost:8080/site/content/b/best-practices.html.

If your requirement is to remove the subfolder from the URL (for example, http://localhost:8080/site/content/about-bloomreach.html), you need to customize link processing.

Approach

Implement a custom HstLinkProcessor to:

  • Remove the subfolder element from generated links that start with content/, so content/a/about-bloomreach becomes content/about-bloomreach.
  • Add the subfolder element when matching incoming URLs, so content/about-bloomreach becomes content/a/about-bloomreach before resolving the document.

Implementation Steps

1. Implement HstLinkProcessor

Create a custom processor by extending HstLinkProcessorTemplate:

site/components/src/main/java/org/example/ExampleHstLinkProcessor.java

package org.example; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.hippoecm.hst.core.linking.HstLink; import org.hippoecm.hst.linking.HstLinkProcessorTemplate; public class ExampleHstLinkProcessor extends HstLinkProcessorTemplate { @Override protected HstLink doPostProcess(HstLink link) { String path = link.getPath(); if (path.startsWith("content/")) { String pattern = "(content/)./(.+)"; Pattern r = Pattern.compile(pattern); Matcher m = r.matcher(path); if (m.find()) { path = m.replaceAll("$1$2"); link.setPath(path); } } return link; } @Override protected HstLink doPreProcess(HstLink link) { String path = link.getPath(); if (path.startsWith("content/")) { String pattern = "(content)(/.)(.?)"; Pattern r = Pattern.compile(pattern); Matcher m = r.matcher(path); if (m.find()) { path = m.replaceAll("$1$2$2$3"); link.setPath(path); } } return link; } }
  • doPostProcess removes the subfolder from the generated link path.
  • doPreProcess adds the subfolder back based on the first character of the document name.

2. Register the Processor in Spring

Configure the processor in your Spring context:

site/components/src/main/resources/META-INF/hst-assembly/overrides/customLinkProcessors.xml

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> <bean id="org.hippoecm.hst.core.linking.HstLinkProcessor" class="org.hippoecm.hst.core.linking.HstLinkProcessorChain"> <property name="processorsInChain"> <list> <bean class="org.example.ExampleHstLinkProcessor" /> </list> </property> </bean> </beans>

Verification

  • Generate a link to a content document. The resulting URL should not include the subfolder (e.g., /content/about-bloomreach.html).
  • Access a URL without the subfolder. The processor should resolve it to the correct document in the repository.
Share Feedback
Page: /build/web-files-links-urls/customize-link-processing
Section: Build
Category *