A part is a building block that can be placed in a region on a page or layout. As with pages, each part is composed of a JavaScript controller, an XML descriptor and an HTML view.

The part descriptor and controller files must be placed in the folder site/parts/[part-name]


The part descriptor is where input fields are defined for custom configuration of the part. The descriptor is not required if the part does not need any custom configuration. Parts cannot contain regions.

When used, the descriptor file must have the same name as the part folder that contains it site/parts/[part-name]/[part-name].xml:

  <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. The controller typically uses library functions to get content and/or configurations and prepare data which it passes to the view file for dynamic rendering.

var portal = require('/lib/xp/portal'); // Import the portal functions
var thymeleaf = require('/lib/xp/thymeleaf'); // Import the thymeleaf render function

// Handle GET requests
exports.get = function(req) {

  // Find the current component from request
  var component = 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('/site/view/my-favorite-things.html');

  // Render a thymeleaf template
  var body = thymeleaf.render(view, model);

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



A part view defines the markup for the part component. The things parameter is basically just JSON data passed from the controller and we can iterate over it easily in Thymeleaf and print its values.

  <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.


The HTML generated for the part view must have a single root element.