-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Declarative Transformations API #356
Declarative Transformations API #356
Conversation
- added `Transformer` class - added import script that can consume transformation objects
- added support for import JSON object
- do not allow custom sections mapping script to bleed into other tabs
- remove test files
@@ -18,14 +18,13 @@ const initOptionFields = (parent) => { | |||
const optionFields = getOptionFields(parent); | |||
optionFields.forEach((field) => { | |||
const value = localStorage.getItem(`option-field-${field.id}`); | |||
if (value !== null) { | |||
if (!field.classList.contains('locked') && value !== null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix to not have the custom sections mapping script bleed into other tabs.
} | ||
} | ||
|
||
export default class Transformer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Transformer
could be added to helix-importer
instead of being bolted on here. This class is where all the logic for processing a import ruleset lives. There are a number of phases that every import can participate in. The blocks
phase is the most involved as there are a number of different parsing options that can be leveraged depending on the complexity of a site.
js/shared/import.js
Outdated
.replace(/[^a-z0-9/]/gm, '-'); | ||
}; | ||
|
||
const createImporter = (rules) => ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A factory for creating compatible import scripts based on an import ruleset.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createImporter
may be an overloaded term so I may try to come up with a more descriptive name.
js/shared/pollimporter.js
Outdated
const isImportScript = Object.keys(mod.default).some((key) => key === 'transformDOM' || key === 'transform'); | ||
if (isImportScript) { | ||
$this.projectTransform = mod.default; | ||
} else { | ||
// declarative transformation | ||
$this.projectTransform = createImportScript(mod.default); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Detect the type of import script and use the createImporter
factory if needed.
js/shared/pollimporter.js
Outdated
const loadJson = (json) => { | ||
try { | ||
const importCfg = JSON.parse(json); | ||
$this.projectTransform = createImportScript(importCfg); | ||
} catch (err) { | ||
console.error('Invalid transformation JSON'); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An import script URL can now also be JSON for a no-code option.
@@ -0,0 +1,10 @@ | |||
/* global WebImporter */ | |||
|
|||
export default function parse(element, { document, params: { cells } }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A generic block parser that is able to generate a Block table from a config object or two-dimensional array of cell rules.
// phase 3: block creation | ||
blocks.forEach((blockCfg) => { | ||
const { type, selectors = [], parse, target = 'replace', params = {} } = blockCfg; | ||
const parserFn = parse || parsers[type] || parsers['block']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Detect the type of parser that should be used.
// parse the element into block items | ||
const items = parserFn.call(this, element, source); | ||
// create the block | ||
const block = WebImporter.Blocks.createBlock(document, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A new function added to helix-importer
. 👉 adobe/helix-importer#351
* @param element Root element to query from | ||
* @param params Object of selector conditions | ||
*/ | ||
static buildBlockConfig(element, params) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function to map an object of name/value pairs with selector logic into a valid block config block.
* @param element | ||
* @param cells | ||
*/ | ||
static buildBlockCells(element, cells) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function to map a two-dimensional array of selectors into actual elements that should be added to a block.
Import Ruleset Example
|
- add defaults to metadata parser
- refactor to `TransformFactory`
- add more comments
- add comments to `TransformFactory`
- add declarative transformation docs
- change `target` prop for blocks to `insertMode`
Description
Introduce a higher-level Importer API that provides a declarative approach to transformations
Related Issue
Fixes: #355
Dependent on: adobe/helix-importer#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. TheTransformer
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: