Parts and Layouts

Contents

Parts and layouts are the building blocks the editors place inside regions to compose pages.

Insert

From Content Studio, editors may insert parts and layouts into regions by right-clicking the page form, or by dragging and dropping them into the visual editor.

The available parts and layouts are determined by the components registered in your project.

Context menu with insert part highlighted - Insert layout is disabled as nested layouts is not allowed
Figure 1. Inserting a part into a region

Configuration

Once added to the page, a part or layout can be configured. The form fields are defined in the component descritor, similar to a content type.

Page form supports validation handling and visualization
Figure 2. Each component may declare a form

Parts

Parts are leaf components in the page structure — they do not contain regions. Parts are typically used in combination with forms, and have a vast range of application areas.

Usage

Place a descriptor in your project: src/main/resources/cms/parts/<part-name>/<part-name>.yaml.

Each part may declare a form using the schema system. The form data will be stored together with each component instance.

Example part descriptor
kind: "Part"
title: "Content List"
form: []

Custom icon

Parts support custom icons that replace the standard part icon in Content Studio. Place an icon (PNG or SVG) in the part folder with the same name as the descriptor.

For example, if the part is called mypart, the icon file should be called either mypart.svg or mypart.png.

Layouts

Layouts are essentially parts that support regions regions. This allows editors to create nested structures of components within the page. Layouts are commonly used to style groups of components in a specific way, or for columnar presentation of parts.

Usage

Place a descriptor in your project: src/main/resources/cms/layouts/<layout-name>/<layout-name>.yaml.

Similar to page descriptors, layouts support both schema forms and regions.

Sample layout with three regions
kind: "Layout"
title: "3 regions"
form: []
regions:
  - name: "left"
  - name: "main"
  - name: "right"

Querying via GraphQL

Guillotine exposes a flat components list. Each entry has a type, a path, and fields such as part or layout containing the corresponding component data. Typed configuration is nested by application and descriptor name; use configAsJson for untyped access.

Typed part config

For a part named featured in com.enonic.app.superhero, with form fields heading and postCount:

{
  guillotine(project: "myproject", branch: "master") {
    get(key: "/site/articles/hello") {
      components {
        type
        path
        part {
          descriptor
          config {
            com_enonic_app_superhero {
              featured {
                heading
                postCount
              }
            }
          }
        }
      }
    }
  }
}
One part entry from data.guillotine.get.components
{
  "type": "part",
  "path": "/main/0",
  "part": {
    "descriptor": "com.enonic.app.superhero:featured",
    "config": {
      "com_enonic_app_superhero": {
        "featured": {
          "heading": "Featured posts",
          "postCount": 5
        }
      }
    }
  }
}

The part field is null on entries of other component types. GraphQL field names replace dots and dashes with underscores; inspect Query Playground for the configuration fields generated from your descriptors.

Untyped config

Use configAsJson when the renderer handles arbitrary component descriptors:

{
  guillotine(project: "myproject", branch: "master") {
    get(key: "/site/articles/hello") {
      components {
        type
        path
        part { descriptor configAsJson }
        layout { descriptor configAsJson }
      }
    }
  }
}

Layouts expose typed fields under layout.config with the same application-and-descriptor nesting. Their regions are represented by component paths in the flat list. See Component list and the Guillotine component reference.


Contents

Contents