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.