Components
Custom Components
A custom component is one you build for your own project, under apps/{project}/components/. Four pieces make it up: a definition resource (a .content.xml whose jcr:primaryType is kes:ComponentType), one or more views that render it, an optional dialog for the fields authors can edit, and, when the component needs logic, a Sling Model (a Java class that gives a component its server-side logic). A custom component does not require a datasource. Add one only when the component must display dynamically supplied content.
Component structure
Start a new component by adding a folder under the applications area of your project. The example below uses mysite as the project name (the Quick Start running example, groupId com.example) and sample-component as the component. The definition file sits at the component root, and the view and dialog live in child folders:
apps/mysite/components/sample-component/ # kes:ComponentType (the .content.xml definition)
common/
content.html # default view (HTL)
edit/
.content.xml # edit dialog (kestros/cms2/dialog)
The content nodes (definition, view, and dialog) ship from the project’s application module as a FileVault content package. The Java Sling Model ships in the bundle produced by that same module.
Sling-Initial-Content. The bundle content loader expects .json node definitions; docview .content.xml files loaded that way land as sling:Folder nodes and the kes:ComponentType is lost. Ship docview via the package (installPackage) and Java via the bundle (installBundle).Definition resource
The definition is the component’s .content.xml at apps/mysite/components/sample-component/.content.xml. Its jcr:primaryType is kes:ComponentType, and it inherits from a parent component through sling:resourceSuperType:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:kes="http://kestros.io/kes/1.0"
jcr:primaryType="kes:ComponentType"
sling:resourceSuperType="kestros/commons/components/kestros-parent"
jcr:title="Sample Component"
componentGroup="test Components"/>
| Property | Type | Req | Value |
|---|---|---|---|
jcr:primaryType | String | Y | Must be kes:ComponentType |
sling:resourceSuperType | String | Rec | kestros/commons/components/kestros-parent, or any other component you are extending from. Project components should extend a base; built-in base components omit this because they are the base. |
jcr:title | String | Rec | Name of the component |
componentGroup | String | Rec | The group this component appears under in the authoring UI |
Component view
Most components carry a common view: the default HTL script that renders it, at apps/mysite/components/sample-component/common/content.html. This is where you write the component’s markup. A view can pull in its Sling Model with data-sly-use and read properties from it (or read node properties directly with ${properties.name}). The Maven archetype scaffolds a placeholder common view for its generated sample component, which you then replace with your own markup:
<sly data-sly-use.sampleComponent="${'com.example.mysite.application.components.SampleComponent'}" />
<p>${sampleComponent.sampleProperty}</p>
Sling Model
A Sling Model supplies the component’s logic. Kestros component models extend BaseComponent and are adaptable from a Resource. Set @Model’s resourceType to the component path so Sling can bind the model to the component automatically. See the Apache Sling Models documentation for the underlying annotations and injectors:
application module (package <group>.application.components), alongside the component it backs. Datasource models live in application too (package <group>.application.datasources): the application module holds every Sling Model that depends on the component libraries, so the core module stays free of them. See Project Structure for the full module layout.@KestrosModel()
@Model(adaptables = Resource.class,
resourceType = "mysite/components/sample-component")
public class SampleComponent extends BaseComponent {
// include methods here
}
@KestrosModel hooks the model into Kestros validation and in-CMS documentation (it can carry a validator and documentation paths). It is optional: the sample sites do not all use it, and a plain @Model works on its own.Getters can be annotated with @KestrosProperty to document the JCR property, provide a default and a sample value, and mark it configurable in the edit dialog:
@KestrosProperty(jcrPropertyName = "sampleProperty",
defaultValue = "",
description = "This is a sample property, which can be edited in the "
+ "component's edit dialog.",
configurable = true,
sampleValue = "Hello World!")
public String getSampleProperty() {
return getProperty("sampleProperty", StringUtils.EMPTY);
}
BaseComponent is Resource-adaptable, so it cannot read the request or its query parameters. Request-scoped data comes from ComponentRequestContext (request-adaptable) in the view, or from a separate request-adaptable model. @KestrosProperty is recommended for documentation but is not required on every getter.Edit dialog
A dialog lets authors edit the component’s properties. Add it at apps/mysite/components/sample-component/edit/.content.xml. Use the cms2 dialog shape: a root with sling:resourceType="kestros/cms2/dialog", a single <content> container (no tabs), then one node per field. Each field carries a name (the JCR property it writes) and a label, and picks its input type through sling:resourceType="kestros/cms2/fields/general/<type>":
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:kes="http://kestros.io/kes/1.0"
jcr:primaryType="nt:unstructured"
sling:resourceType="kestros/cms2/dialog">
<content jcr:primaryType="nt:unstructured">
<text jcr:primaryType="nt:unstructured"
sling:resourceType="kestros/cms2/fields/general/textfield"
name="sampleProperty"
label="Sample Property"
focused="{Boolean}true"/>
</content>
</jcr:root>
kestros/cms/dialog format. The older kestros/cms/dialog format used a different field vocabulary (fields addressed the property with propertyName= rather than name=). The cms2 shape shown above is the supported one for new components.General fields are referenced as sling:resourceType="kestros/cms2/fields/general/<type>". A few common ones (see Dialogs for the complete list of 19):
| Field type | resourceType suffix | What it’s for |
|---|---|---|
textfield | general/textfield | Single-line text input |
selectfield | general/selectfield | Dropdown select from a list of options |
richtext | general/richtext | Rich-text (formatted) editor |
multifield | general/multifield | Repeatable group of fields (a list of entries) |
Kestros pickers are referenced as sling:resourceType="kestros/cms2/fields/kestros/<type>": component-picker, datasource-picker, layout-picker, theme-picker, and variations-picker.