A part is a building block that can be placed on a page or into a region. As with pages, a part is composed of a descriptor, a controller and and optionally - a view.

The part descriptor is required to register the part and allows us to set up user input fields to configure the part. A part cannot contain any regions.

  <display-name>My favorite things</display-name>
    <field-set name="things">
        <input type="TextLine" name="thing">
          <occurrences minimum="0" maximum="5"/>

To drive this part, we will also need a controller controller.js.

exports.get = function(portal) {

  // Find the current component from request
  var component = execute('portal.getComponent');

  // Find a config variable for the component
  var things = component.config["thing"] || [];

  // Define the model
  var model = {
    component: component,
    things: things

  // Resolve the view
  var view = resolve('/cms/view/my-favorite-things.html');

  // Render a thymeleaf template
  var body = execute('thymeleaf.render', {
    view: view,
    model: model

  // Return the result
  return {
    body: body,
    contentType: 'text/html'


The part needs a root element with the attribute data-portal-component-type. In this case, it will be a part, but we can also resolve it dynamically as explained in the example. The things parameter is basically just JSON data, and we can loop it easily in Thymeleaf and print its value.

<section data-th-attr="data-portal-component-type=${component.type}">
  <h2>A list of my favorite things</h2>
  <ul class="item" data-th-each="thing : ${things}">
    <li data-th-text="${thing}">A thing will appear here.</li>

The part can now be added to the page via drag and drop. You will be able to configure the part in the context window in live-edit.