Enigmatic parsys and ComplexComponent.java - reggie7/aem-tools GitHub Wiki

Many features rely heavily on the custom parsys that is used throughout the whole project instead of the built-in one. It extends foundation/components/parsys and overrides the main script, but what is actually important here is the fact that we can add custom selectors to the original parsys.

Custom new area text

Every parsys instance in the project can have its own custom replacement text for the default Drag components or assets here:

custom parsys new text

Usage

Configuration for this feature is made as easy as possible probably: one needs to simply alter the designs (where the allowed components go anyway) by adding the following node right under the one corresponding to the parsys to be customized:

<new jcr:primaryType="nt:unstructured"
	cq:emptyText="Drag my components here" />

So the node name is new and its property cq:emptyText drives the configuration.

Under the hood

There are two approaches used within aem-tools that needed to be implemented to work separately for both kinds of UI. In Classic UI it's quite straighforward - new.jsp reads the value from currentStyle and alters editConfig's properties accordingly. The same approach failed for Touch UI where currently an even uglier hack is in place. The function hasPlaceholder from Inspectable.js drives the rendered text value, so I've overlaid it with my own implementation that uses the existing designs approach described above. The overlaid function needs to fetch a config JSON that is supplied from parsys via config.json script.

One must take into account it will not work forever in AEM > 6.3 since Inspectable.js says: *WARNING:* This class will probably be deprecated and then merged into the Editable class in the future.

Search Paths

Parsys got equipped with a small handy script sp.html to aid designs creation. Its purpose is to render all the search paths for a given parsys. Given e.g. /content/enigmatic/jcr:content/content parsys resource we'd enter /content/enigmatic/jcr:content/content.sp.html and get the full list.

ComplexComponent

Some of the parsys' selector scripts are using a core Sling Model java class pl.enigmatic.aem.ComplexComponent. It's purpose is to describe the relation between the current resource (i.e. the one that is using the model in a script) and the target resource of a special mode. Thus it exposes the following properties:

  • target - a String property that holds the JCR path to the resource that holds the focus currently (property comes from the URL parameter),
  • expand - a boolean that answers the question: "Am I the target resource?". So if expand is true it means that the target property is equal to the path of the current resource,
  • outer - a boolean that answers the question: "Am I an ancestor of the target resource?". So if outer is true it means that the current resource is somewhere directly on the path from the root to target resource,
  • inner - a boolean that answers the question: "Am I a descendant of the target resource?". So if inner is true it means that the target resource is somewhere directly on the path from the root to current resource,
  • unrelated - a boolean that, if true - means that the current resource is not the target resource (expand is false) and it is neither outer nor inner in relation to the target,
  • child - a String that holds a path of the target resource relative to the current resource (if the latter is its ancestor, so basically when outer is true),
  • parent - a boolean that answers the question: "Am I the parent of the target resource?".

Let's consider this resource tree example:

complex java example

and assume that we have target="/content/enigmatic/table/jcr:content/content/table/rows/row_1". In this setup the following are the values of the above properties depending on the current resource resource:

  • resource=/content/enigmatic/table/jcr:content/content:
    • expand = false
    • outer = true
    • inner = false
    • unrelated = false
    • child = "table"
    • parent = false
  • resource=/content/enigmatic/table/jcr:content/content/table/header:
    • expand = false
    • outer = false
    • inner = false
    • unrelated = true
    • child = null
    • parent = false
  • resource=/content/enigmatic/table/jcr:content/content/table/rows:
    • expand = false
    • outer = true
    • inner = false
    • unrelated = false
    • child = "row_1"
    • parent = true
  • resource=/content/enigmatic/table/jcr:content/content/table/rows/row_1:
    • expand = true
    • outer = false
    • inner = false
    • unrelated = false
    • child = null
    • parent = false
  • resource=/content/enigmatic/table/jcr:content/content/table/rows/row_1/items:
    • expand = false
    • outer = false
    • inner = true
    • unrelated = false
    • child = null
    • parent = false