Folder Picker in a Hippo CMS Component
Hippo CMS has built-in support for configuring components through auto-generated dialogs in the Channel Editor. These can easily be defined by using annotations in the component's ParametersInfo interface. Although there's an option to open a document picker, the documentation only hints at different configurations for it. It isn't clear how to use it for picking a content folder instead of a document.
Thanks to search engines, I stumbled upon a list of supported values for the pickerConfiguration parameter mentioned in passing in a completely different section of documentation. Based on this information, I could use the Console and find the values defined in /hippo:configuration/hippo:frontend/cms/cms-pickers. Unfortunately, none of the values achieved the desired result, not even cms-pickers/folders or cms-pickers/documents-folders-only. I could still select documents in the picker, but not folders.
In the end, the correct parameter to use turned out to be pickerSelectableNodeTypes. By looking at the content in the Console, I determined that I wanted to restrict the picker to the hippostd:folder node type. Even with this parameter set, other node types (e.g. documents) are still shown in the picker but they can't be selected. Not a perfect behavior, but close enough. It's something that can be explained to the editors configuring the component.
This is the final state of my ParametersInfo interface:
public interface FolderPickerComponentInfo {
@Parameter(
name = "Content folder",
required = true
)
@JcrPath(
pickerConfiguration = "cms-pickers/documents-folders-only",
pickerSelectableNodeTypes = { "hippostd:folder" },
isRelative = true
)
String getContentFolder();
}
In the component, I retrieve the list of documents from the selected folder and pass it on to the template:
@ParametersInfo(
type = FolderPickerComponentInfo.class
)
public class FolderPickerComponent extends CommonComponent {
@Override
public void doBeforeRender(HstRequest request, HstResponse response) {
super.doBeforeRender(request, response);
FolderPickerComponentInfo paramInfo = getComponentParametersInfo(request);
List<HippoDocumentBean> contentDocuments = Collections.emptyList();
String folderPath = paramInfo.getContentFolder();
if (folderPath != null) {
HippoFolder folder = getHippoBeanForPath(folderPath, HippoFolder.class);
if (folder != null) {
contentDocuments = folder.getDocuments();
}
}
request.setAttribute("contentDocuments", contentDocuments);
}
}
In the template, I can then render any information about these documents:
<#include "../include/imports.ftl">
<#-- @ftlvariable name="contentDocuments" type="java.util.List<org.hippoecm.hst.content.beans.standard.HippoDocumentBean>" -->
<#list contentDocuments>
<ul>
<#items as content>
<li>${content.displayName}</li>
</#items>
</ul>
<#else>
<p>No documents</p>
</#list>
After registering the template in /hst:hst/hst:configurations/hippofolderpicker/hst:templates:
/folder-picker:
jcr:primaryType: hst:template
hst:renderpath: webfile:/freemarker/hippofolderpicker/folder-picker.ftl
And the component in /hst:hst/hst:configurations/hippofolderpicker/hst:catalog:
/folder-picker:
jcr:primaryType: hst:containeritemcomponent
hst:componentclassname: com.damirscorner.blog.samples.components.FolderPickerComponent
hst:label: Folder Picker
hst:template: folder-picker
hst:xtype: item
The newly crested component appears in the Channel Editor where it can be added to a page and configured using the built-in content picker:

The functionality wasn't difficult to implement. It just took longer than necessary because of incomplete documentation. That's something that happens too often when working with Hippo CMS.
