Rich text

Contents

Guillotine exposes HtmlArea fields as the RichText type, with raw and processed HTML plus structured information about links, images and macros.

The examples use the myproject project and an illustrative com.example.myapp:post content type. Replace the project, content paths, generated type names and form fields with those shown in your Playground schema. Send these queries using the request format on the Usage page.

Processed HTML

Retrieve blog posts with an author reference, tags and an HtmlArea field named text:

{
  guillotine(project: "myproject", branch: "master") {
    queryDsl(
      query: {
        term: {
          field: "type"
          value: { string: "com.example.myapp:post" }
        }
      }
      first: 10
    ) {
      ... on com_example_myapp_Post {
        data {
          author {
            displayName
          }
          tags
          text {
            processedHtml
          }
        }
      }
    }
  }
}

processedHtml contains HTML with resolved links, images and macro placeholders. The structured fields described below support custom rendering in your client.

Internal links to media and content are replaced with URLs generated by XP.

For page links embedded in HTML, XP uses the selected site’s configured Base URL. Sites do not inherit a Base URL from their parent; without one, links fall back to the site engine address. The selected site context determines the relative path; see Base URLs.

If your frontend uses different routes, use the structured link data to build links from pageUrl.path and pageUrl.queryString with your own deployment context.

Processed internal links receive a data-link-ref attribute identifying the referenced content. Use it to match the link with the structured data in the links field.

For instance, the processed value of a link looks like this:

<p>
    <a title="Tooltip"
        href="https://www.example.com/posts/related-post"
        data-link-ref="e72f48b6-a972-4133-a300-a3ab5d132800">Link 1</a>
</p>

The GraphQL query below will process links inside the field:

query {
  guillotine(project: "myproject", branch: "master") {
    get(key: "/my-site/posts/first-post") {
      ... on com_example_myapp_Post {
        data {
          text {
            links {
              ref          (1)
              uri          (2)
              media {      (3)
                content {
                 _id
                }
                intent     (4)
                mediaUrl {
                  path
                  queryString
                }
              }
              content {    (5)
                _id
              }
              pageUrl {    (6)
                path
                queryString
              }
            }
          }
        }
      }
    }
  }
}
1 Reference to link in the processedHtml field
2 Link URI
3 Related media content and attachment link components. This field has null value for non-media content
4 Link intent. Available values download and inline
5 Related content. This field has null value for media content
6 Page link components for your frontend routing. This field has null value for media links

Images

Guillotine by default provides image processing in the processedHtml field of the RichText GraphQL type. Internal image references are replaced with generated media URLs, and each img tag receives a data-image-ref attribute containing the referenced content ID. Using that reference you will be able to find image details in the images field and implement custom image processing, if needed.

Media links embedded in HTML follow XP’s media base configuration and contextual API mounts. For custom rendering, build image links from the structured image data using your client’s media base and the returned imageUrl.path and imageUrl.queryString.

For instance, the processed value of an image looks like this:

<figure class="editor-align-justify">
    <img alt="Alt text"
         src="/media:image/myproject/contentid:fingerprint/width-768/photo.jpg"
         data-image-ref="4f2439ff-ecef-4470-a4b4-d8929bce6ee2" />
    <figcaption>Caption text</figcaption>
</figure>

The query below will process images inside the field:

query {
  guillotine(project: "myproject", branch: "master") {
    get(key: "/my-site/posts/first-post") {
      ... on com_example_myapp_Post {
        data {
          text {
            images {
              ref                           (1)
              image {                       (2)
                ... imageFragment
              }
              style {                       (3)
                name
                aspectRatio
                filter
              }
            }
          }
        }
      }
    }
  }
}

fragment imageFragment on Content {
  _id
  type
  ... on media_Image {
    data {
      caption
    }
  }
  ... on media_Vector {
    data {
      caption
    }
  }
}
1 Reference to an image in the processedHtml field
2 Image as Content type
3 Image style as ImageStyle type

Use the processHtml argument, of type ProcessHtmlInput, on an HtmlArea field to control image processing. Setting imageWidths generates URLs for the requested widths and adds a srcset attribute to the image tags.

For example:

{
  guillotine(project: "myproject", branch: "master") {
    get(key: "/my-site/posts/first-post") {
      ... on com_example_myapp_Post {
        data {
          text(processHtml: { imageWidths: [600, 992] }) {
            processedHtml
            images {
              ref
            }
          }
        }
      }
    }
  }
}

The result will look as follows:

<figure class="editor-align-justify">
    <img alt="Alt text"
         src="/media:image/myproject/contentid:fingerprint/width-768/photo.jpg"
         data-image-ref="4f2439ff-ecef-4470-a4b4-d8929bce6ee2"
         srcset="/media:image/myproject/contentid:fingerprint/width-600/photo.jpg 600w,
                 /media:image/myproject/contentid:fingerprint/width-992/photo.jpg 992w"/>
    <figcaption>Caption text</figcaption>
</figure>

Macros

Each macro will be translated to an editor-macro tag with data-macro-ref and data-macro-name attributes in the processedHtml field value. Using these references you will be able to find details of a specific macro in the macrosAsJson or macros fields and implement custom macro processing if needed.

Guillotine processes macros which have a descriptor and built-in macros called disable and embed, otherwise processing will be skipped. More details about macros.

For instance, we have an input form item called description of HtmlArea type which contains the embed macro as shown below:

Embed Macro

The query below will fetch data for the description field:

query {
  guillotine(project: "myproject", branch: "master") {
    get(key: "/my-site/posts/first-post") {
      ... on com_example_myapp_Post {
        data {
          description {
            raw            (1)
            processedHtml  (2)
            macrosAsJson   (3)
            macros {       (4)
              ref
              name
              descriptor
              config {
                embed {
                  body
                }
              }
            }
          }
        }
      }
    }
  }
}
1 Non-processed value of the description field
2 Processed value of the description field
3 Array of processed macros in JSON format. The order of macros will be the same as in the raw and processedHtml fields.
4 Macro allows to specify necessary fields. That field is an alternative for macrosAsJson field

Results of the query:

Response for embed macro

Custom macros use a macro schema to define their parameters. For example, a testmacro macro with a default_text input is declared at /cms/macros/testmacro/testmacro.yaml, relative to the app resource root. In a Gradle project, this is src/main/resources/cms/macros/testmacro/testmacro.yaml.

kind: Macro
title:
  text: Current user
description:
  text: Shows the currently logged-in user
form:
  - type: TextLine
    name: default_text
    label: Text to show if no user is logged in

Select default_text to retrieve the macro parameter defined by this schema:

query {
  guillotine(project: "myproject", branch: "master") {
    get(key: "/my-site/posts/first-post") {
      ... on com_example_myapp_Post {
        data {
          description {
            macros {
              ref
              name
              descriptor
              config {
                testmacro {
                  default_text
                }
              }
            }
          }
        }
      }
    }
  }
}

Contents

Contents