adobe / helix-importer-ui

Apache License 2.0
20 stars 25 forks source link

Declarative Transformations API #356

Closed arumsey closed 1 month ago

arumsey commented 1 month ago

Description

Introduce a higher-level Importer API that provides a declarative approach to transformations

Related Issue

Fixes: #355

Dependent on: https://github.com/adobe/helix-importer/pull/351

Motivation and Context

The AEM Importer import scripts are a powerful tool for manipulating a DOM into an Edge Delivery compatible format. These scripts however need to be written by developers with a high degree of knowledge of DOM APIs. The addition of a declarative transformation API on top of the existing low-level import script opens mor doors for less technical users to begin importing content by simply defining a collection of CSS selectors. Additionally, a no-code approach to defining import rules also allows them to be more easily created by automation and for them to be POSTED to a service to enable long running imports.

This feature does not introduce any breaking changes to the AEM Importer. The import script however can now be a JSON file or a JS object. This JSON structure (the ruleset) can then be passed to a createImporter factory that generates a valid import script. The Transformer class is able to consume a ruleset and runs through a series of phases to clean up the DOM and then generate any desired blocks through the use of CSS selector logic.

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

Checklist:

arumsey commented 1 month ago

Import Ruleset Example

{
  "root": "main",
  "cleanup": {
    "start": [
      ".cookie-status-message",
      ".breadcrumbs",
      ".messages",
      ".sidebar",
      "h1 + ul.instruments-menu",
      "h1"
    ]
  },
  "blocks": [
    {
      "type": "metadata",
      "target": "append",
      "params": {
        "metadata": {
          "keywords": "[name=\"keywords\"]",
          "Publication Date": "[property=\"og:article:published_time\"]",
          "category": [
            [":scope:has(.is-blog .post-list) .webinar-speaker-img", "Webinars"],
            [":scope:has(.is-blog .post-list)", ""]
          ],
          "series": [
            [":has(.is-blog .post-list) .webinar-speaker-img", ""]
          ],
          "eventDate": [
            [":has(.is-blog .post-list) .webinar-speaker-img", ""]
          ],
          "speakers": [
            [":has(.is-blog .post-list) .webinar-speaker-img", ".webinar-speaker-img + strong"]
          ]
        }
      }
    },
    {
      "type": "overview",
      "selectors": [
        ".entry div:has(div > p > img)",
        ".entry > div > div:first-of-type:has(div > img)"
      ],
      "params": {
        "cells": [
          ["div:has(p > img)", ":scope > div:last-child"]
        ]
      }
    },
    {
      "type": "columns",
      "selectors": [
        ".entry > .about-content",
        ".desc-img-wrapper:has(> :nth-child(2):last-child)"
      ]
    }
  ]
}