Understand what template queries are, what they are used for, and where they are stored in the repository.
CMS users can create new documents and subfolders within existing content folders. They do this by browsing to a folder, opening its context menu, choosing one of the available "Add ..." options, and choosing one of the document or folder types available for that option. The new document or folder is then created by copying the appropriate template to the selected parent folder and substituting any of the template's default property values if needed.
Template queries are used to define the available "Add ..." options, the available document or folder types, and the substitution patterns to use when copying the template.
This page describes the node types and properties used to configure template queries, and how they relate to each other. They are illustrated with some basic examples.
For a detailed hands-on example of defining and using custom template queries, see Control Which Document Types Can Be Used in Which Folder.
A template query generator is packaged with the Essentials development tools, providing an easy way to create template queries for custom document types.
Folder Types and Template Queries
Content folders, which are nodes of type hippostd:folder, have a multi-valued String property called hippostd:foldertype. Each value of this property refers to a template query, and is rendered as an "Add ..." option in the folder's content menu in the CMS UI.
Template queries are stored as nodes of type hippostd:templatequery at the following repository location:
The hippostd:templatequery type inherits from the built-in JCR node type nt:query and as such has two properties that represent the query:
[nt:query] > nt:base - jcr:statement (string) - jcr:language (string)
where the first property contains the query statement and the second the query language in which the statement is written (xpath, sql, JCR-SQL2, or JCR-JQOM).
The query should select the template nodes of the document or folder types that the user should be able to choose for the corresponding "Add ..." option.
For documents, templates are stored as "prototype" document within the document type definitions. For example:
For folders, templates are stored within the template query node structure. For example:
Exclude Explicit Primary NodeTypes
Instead of excluding certain primary nodetypes by incorporating it into the hippostd:templatequery it is possible to add to the hippostd:templatequery the property
For the default provided new-document template query stored at /hippo:configuration/hippo:queries/hippo:templates/new-document by default an empty hippostd:excludePrimaryTypes:  is configured, to which you can bootstrap extra nodetypes to be excluded from the result. A use case is for example the hippo taxonomy plugin, which adds a new document type hippotaxonomy:taxonomy which by default became available for the new-document template query, however, the functional use case was that taxonomy documents should not be possible to add below folders. Therefore, the taxonomy project also bootstrap:
definitions: config: /hippo:configuration/hippo:queries/hippo:templates/new-document: hippostd:excludePrimaryTypes: operation: add value: [hippotaxonomy:taxonomy]
which makes sure tht new-document template query does not return taxonomy document as option.
Taking a Bloomreach Experience Manager project created using the Maven archetype using the default settings, consider the following example:
The default content root folder /content/documents/myproject has two "folder types" defined:
/content/documents/myproject: jcr:primaryType: hippostd:folder hippostd:foldertype: [new-translated-folder, new-document]
Each of the values of the hippostd:foldertype property refers to a template query stored as a child node of /hippo:configuration/hippo:queries/hippo:templates.
Localized labels for template queries are defined in resource bundles under /hippo:configuration/hippo:translations/hippo:templates:
/hippo:configuration/hippo:translations/hippo:templates: jcr:primaryType: hipposys:resourcebundles /en: jcr:primaryType: hipposys:resourcebundle new-document: new document new-translated-folder: new translated folder
In the CMS UI, when the user opens the context menu for the myproject folder, a localized menu option is displayed for each template query referred to in the folder's hippostd:foldertypes property:
Now take a look at the relevant structure and properties of the new-translated-folder template query node:
/hippo:configuration/hippo:queries/hippo:templates/new-translated-folder: jcr:primaryType: hippostd:templatequery /hippostd:templates: jcr:primaryType: hippostd:templates /hippostd:folder: jcr:primaryType: hippostd:folder hippostd:foldertype: [new-translated-folder, new-document] jcr:language: xpath jcr:statement: /jcr:root/hippo:configuration/hippo:queries/hippo:templates/new-translated-folder/hippostd:templates/node()
Note that the folder template is defined within the template query node structure, and contains the hippostd:foldertype values for the new folder that will be created using this template.
Also note that the query statement selects any template nodes defined within this template query node structure.
In the CMS UI, when the user selects the Add new translated folder option, a dialog appears in which the user can enter a name for the new folder. Because this template query has only one result, there is no option in the dialog to select the folder type.
Now take a look at the properties of the new-document template query node:
/hippo:configuration/hippo:queries/hippo:templates/new-document: jcr:primaryType: hippostd:templatequery jcr:language: xpath jcr:statement: //element(*,hipposysedit:namespacefolder)/element(*,mix:referenceable)/element(*,hipposysedit:templatetype)/hipposysedit:prototypes/element(hipposysedit:prototype,hippo:document)
Note that the query statement selects all hipposysedit:prototype nodes of type hippo:document within the document type definitions in the namespace folder (/hippo:namespaces). Because all document types descend from hippo:document, a folder defining this template query in its folder types allows users to create documents of any type inside that folder.
In the CMS UI, when the user selects the Add new document option, a dialog appears in which the user can enter a name for the new document. Because this template query has multiple results, the user must also select a document type from a dropdown list.
As explained above, when a user creates a new document or folder, the appropriate template is copied to the selected parent folder. Typically, the default values for some document or folder properties depend on the context in which it is created. For example, the current date, the current user, or values entered by the user in the create document/folder dialog.
For this purpose, template query nodes have a multi-valued property hippostd:modify which contains relative paths to properties of the template nodes with the values to be substituted when copying the template to the new document or folder during creation. The special _name pseudo property allows modifying the name of the node.
The values of the hippostd:modify property alternate between the path to the property to be substituted and the value to substitute it with. The paths are relative to the root of the template selected by the query and can contain the special wildcard path element matcher _node that matches any node. The following table specifies the special substitution values available:
|$name||The URL name specified in the create document/folder dialog.|
|$holder||The id of the current user.|
|$now||Current date-time specified in the format yyyy-MM-dd'T'HH:mm:ss.SSSZ|
|$inherited||The value of the property is copied from the parent node.|
|$uuid||A newly created UUID.|
Optional math functions may be used along with the $now option, time units supported include:
- Y for year
- M for month
- D for day
- H for hour
- MIN for minute
- SEC for second
- MIL for millisecond
Some example usages are:
- $now/H: Round to the start of the current hour
- $now/D: Round to the start of the current day
- $now+2Y: Exactly two years in the future from now
- $now-1D: Exactly 1 day prior to now
- $now+6M+3D/D: 6 months and 3 days in the future from now, rounded down to nearest day
Properties specified in hippostd:modify must exist on the template node for the substitution to take place. If a property specified in hippostd:modify doesn't exist on the template node, it is not created but rather ignored.
The template query new-translated-folder has the following hippostd:modify values:
/hippo:configuration/hippo:queries/hippo:templates/new-translated-folder: jcr:primaryType: hippostd:templatequery hippostd:modify: [./_name, $name, ./hippotranslation:id, $uuid, ./hippotranslation:locale, $inherited]
These values are interpreted as follows:
- The new node's name will be the URL name specified in the create document/folder dialog.
- The new node's hippotranslation:id property will have its value substituted by a newly generated UUID.
- The new node's hippotranslation:locale property will have its value subsituted with the value of the same property of the new item's parent node.
The template query new-document has many more interesting hippostd:modify value pairs, including:
Substitutes the hippostdpubwf:createdBy property's default value with the username of the user who created the document.
Substitutes the hippostdpubwf:creationDate property's default value with the current date.