Rich text

Contents

Rich text is structured, author-edited HTML — typically entered via the HtmlArea form item. It can include inline images, links to other content items, custom styles, and macros.

Raw format

Rich text is stored as HTML with Enonic-specific markup for internal references:

  • Internal links<a href="content://<contentId>">…​</a>

  • Image links<img src="image://<imageId>" />

  • Opinionated image component<figure><img src="image://<imageId>" /><figcaption>Optional caption</figcaption></figure>

  • Macros — plain-text instructions in square brackets, for example

Example of raw stored HTML:

<h3>Welcome</h3>
<p>Read our <a href="content://f3076b5c-ea45-4c8b-8c06-1f87b8d8cdd9">latest post</a>.</p>
<figure><img src="image://a1b2c3d4-e5f6-7890-abcd-ef1234567890" /></figure>

Internal references and macros must be resolved before rendering. Guillotine exposes both a raw and a processed variant.

Processed output

Visit the React SPA tutorial for hands-on examples of client-side rendering.

Guillotine’s processedHtml resolver optimizes the raw HTML, by adding reference attributes which can be used client-side to replace the standard markup with elements optimized for your front-end, for example:

  • content://<id> links → relative or absolute content URLs

  • image://<id> references → <img> tags served by the Image API, with any custom image styles applied server-side

  • Macros → rendered HTML produced by each macro’s function (the built-in embed macro passes its body through unchanged)

Use processedHtml when rendering; use the raw value or dataAsJson when the front-end needs to do its own processing.

GraphQL example

{
  guillotine {
    get(key: "/articles/hello") {
      displayName
      ... on com_example_myapp_Article {
        data {
          body {
            raw
            processedHtml(type: ABSOLUTE)
            images {
              _id
              imageUrl(scale: "width(800)")
            }
            links {
              ... on com_example_myapp_Article {
                _path
                displayName
              }
            }
            macros {
              name
            }
          }
        }
      }
    }
  }
}
Response
{
  "data": {
    "guillotine": {
      "get": {
        "displayName": "Hello world",
        "data": {
          "body": {
            "raw": "<p>Read our <a href=\"content://f3076b5c-...\">latest post</a>.</p>",
            "processedHtml": "<p>Read our <a href=\"https://example.com/articles/latest-post\">latest post</a>.</p>",
            "images": [
              {
                "_id": "a1b2c3d4-...",
                "imageUrl": "/api/media:image/my-project/a1b2c3d4-...:<fingerprint>/width-800/photo.jpg"
              }
            ],
            "links": [
              {
                "_path": "/articles/latest-post",
                "displayName": "Latest post"
              }
            ],
            "macros": [
              { "name": "embed" }
            ]
          }
        }
      }
    }
  }
}

Beyond raw and processedHtml, the HtmlArea GraphQL type also exposes images, links, and macros as typed fields — useful when a front-end needs structured data about references rather than parsing HTML. See the Guillotine documentation for the full type definition.

Front-end toolkits

Rendering processed rich text in a front-end framework — mapping content URLs to routes, swapping image references for responsive <picture> tags, and rendering macros as components — is non-trivial to do by hand. Enonic publishes React components and a Next.js integration (Next.xp) that handle these steps for you. See the Frameworks section for more.


Contents

Contents