Dialog Conversion Tool

You are reading the AEM 6.2 version of Dialog Conversion Tool.
This documentation is also available for the following versions:  AEM 6.1  AEM 6.0 

The dialog conversion tool is provided to help you extend existing components that only have a dialog defined for the classic UI (based on ExtJS). The tool uses this original dialog to create a duplicate dialog designed for the touch-optimized UI (based on Granite UI/CoralUI).

The goal of this tool is to automate the upgrade (as far as possible) to increase efficiency and reduce errors.

Caution

The result must be verified and possibly adjusted further. The tool cannot cover every scenario, as its conversion rules are non-exhaustive and operate on a best-effort basis. The tool is intended as an aid, to kickstart the conversion by converting the bulk of a dialog.

It converts the most frequently used elements and properties, but the conversion will be incomplete when dealing with customizations or highly-specialized dialogs. The tool will still create the new dialog for the touch-optimized UI, but it will skip what it cannot convert. So the resulting dialog might contain nodes from the classic dialog copied as-is (if no rule matched that specific widget). Or a converted widget might miss some properties, as there was no appropriate rule to convert them.

Download and Install the Dialog Conversion Tool

  1. Install the package on your instance.

Converting a Dialog

The tool extends existing components that only have dialogs designed for the classic UI. It does this by creating a corresponding dialog for the touch-optimized UI at the same location in the content tree (component definition):

  • Dialog for classic UI: 
    • name dialog
    • type cq:Dialog
  • Dialog for touch-optimized UI: 
    • name cq:dialog

Use the following steps to convert one or more dialogs:

  1. Open the Dialog Conversion console, accessible from Tools, Operations:

    http://<hostname>:<port-nr>/libs/cq/dialogconversion/content/console.html

    file
  2. Enter the required path; for example, /apps/geometrixx/components. You can also enter a direct path to a single dialog; e.g. /apps/geometrixx/components/lead.

    file
  3. Select Show dialogs to display all dialogs below that location:

    file

    A table lists all dialogs (at all levels) below the specified path.

    • Dialog (Classic UI)
      All nodes of type cq:Dialog and having the node name dialog are selected for display.
    • Each row contains Links to:
      • show the dialog in the classic UI
      • view its node structure in crxde (CRXDE Lite)
    • Dialog (Touch UI)
      Shows when a dialog for the touch-optimized UI has already been created; comparable links are provided for the touch-optimized UI dialog. This is determined when the dialog node has a sibling node named cq:dialog. Once the touch-optimized dialog exists the item can not be selected for conversion.

    Note

    Components that do not have a dialog for the classic UI at all (i.e. they were designed purely for the touch-optimized UI) are not listed.

  4. Select one or more dialogs for convert:

    file
  5. Tap/click on Convert <x> dialogs to start the process.

    file
  6. Select Show dialogs to return to the list:

    file

Dialog Rewrite Rules

The implementation of the conversion tool is based on the concept of graph rewriting, where a graph is transformed by applying a set of rewrite rules. When a rule matches a specific subgraph it is applied to replace that occurrence with a replacement graph (see also http://en.wikipedia.org/wiki/Graph_rewriting).

The dialog conversion tool uses this approach to rewrite a given dialog tree, designed for the classic UI, to its counterpart for the touch-optimized UI.  

Typically, a single dialog rewrite rule is responsible for rewriting a single dialog element, for example the pathfield widget. The algorithm traverses the dialog tree and applies matching rewrite rules according to their priority (determined by the ranking of the rule). This is repeated until no rule matches (the rewrite rules must therefore be careful not to create rewrite loops).

The rewrite rules can be defined in two different ways, either as:

Some are provided out-of-the-box, but you can also define your own customized rules (both node-based and java-based).

Rewrite Rules Provided

The dialog conversion tool includes several predefined rewrite rules.  They cover the following classic UI widgets (see Using xtypes for more information):

button, checkbox, combobox, cqinclude, datetime, dialog, dialogfieldset, fieldset, fileuploadfield, hidden, numberfield, hidden, multifield, numberfield, panel, password, pathfield, radio, radiogroup, select, sizefield, tabpanel, tags, textfield, textarea

Node-based Rewrite Rules

A dialog rewrite rule can be defined in terms of nodes and properties:

rule
  - jcr:primaryType = nt:unstructured
  - cq:rewriteRanking = 4
  + patterns
    - jcr:primaryType = nt:unstructured
    + foo
      - ...
      + ...
    + foo1
      - ...
      + ...
  + replacement
    + bar
      - ...
      + ...
        

Code samples are intended for illustration purposes only.

This example defines a rule containing two patterns (the trees rooted at foo and foo1) and a replacement (the tree rooted at bar). The pattern and replacement trees are arbitrary trees containing nodes and properties. The rule matches a subtree if any of the defined patterns matches. For a pattern to match, the tree in question must contain the same nodes as the pattern (matching names, except for the root), and all properties defined in the pattern must match the properties on the tree. A node in a pattern can be marked as optional by setting cq:rewriteOptional to true, in which case it doesn't have to be present for a tree to match.

In the case of a match, the matched subtree (called original tree) will be substituted by the replacement. The replacement tree can define mapped properties that will inherit the value of a property in the original tree. They need to be of type String and have the following format:

${<path>}

If the referenced property doesn't exist in the original tree, then the property is omitted in the replacement. Alternatively, a default value can be specified for that case (only possible for String properties):

${<path>:<default>}

Mapped properties can be multivalued, in which case they will be assigned the value of the first property that exists in the original tree. The following example illustrates mapping properties:

...
  + replacement
    + bar
      - prop = ${./some/prop}
      - default = ${./non/existing:default string value}
      - multi = [${./non/existing}, ${./some/prop}]
        

Code samples are intended for illustration purposes only.

The replacement tree additionally supports the following special properties (named cq:rewrite...):

  • cq:rewriteMapChildren (String)
    Copies the children of the referenced node in the original tree to the node containing this property (e.g. cq:rewriteMapChildren=./items will copy the children of ./items to the current node).

  • cq:rewriteIsFinal (Boolean)
    Set this property on a node that is final and can be disregarded for the rest of the conversion as an optimization measure. When placed on the replacement node itself (i.e. on rule/replacement), the whole replacement tree is considered final.

Defining Your Own Node-based Rewrite Rules

The rewrite rules provided are defined at:

/libs/cq/dialogconversion/rules

These rules can be overwritten by providing a set of rules at:

/apps/cq/dialogconversion/rules

You can copy /libs/cq/dialogconversion/rules to /apps then modify existing and/or add new rules to this new instance.

Java-based Rewrite Rules

More complex rewrite rules can be defined as Java classes exposing an OSGi service of the interface:

com.adobe.cq.dialogconversion.DialogRewriteRule

Such a class must implement following methods:

boolean matches(Node root) throws RepositoryException;
Node applyTo(Node root, Set<Node> finalNodes) throws DialogRewriteException, RepositoryException;
int getRanking();
        

Code samples are intended for illustration purposes only.

The matches method must return true if the rule matches the subtree rooted at the supplied root node. If the rule matches, the tree rewriting algorithm will subsequently call the applyTo method, which must rewrite the subtree rooted at the specified root node. Usually, this method will temporarily rename the original tree, build the new tree as a new child of the original tree's parent node (using its nodes and properties) and finally remove the original tree. More detailed information can be found in the Javadoc of the com.adobe.cq.dialogconversion.DialogRewriteRule interface.

Further information - Javadocs

For further information see the Javadocs for com.adobe.cq.dialogconversion.

Defining Your Own Java-based Rewrite Rules

The following class shows an example of a custom rewrite rule implementing the com.adobe.cq.dialogconversion.DialogRewriteRule interface:

@Component
@Service
public class CustomDialogRewriteRule implements DialogRewriteRule {
 
    public boolean matches(Node root) throws RepositoryException {
        // ...
    }
 
    public Node applyTo(Node root, Set<Node> finalNodes) throws DialogRewriteException, RepositoryException {
        // ...
    }
 
    int getRanking() {
        // ...
    }

}
        

Code samples are intended for illustration purposes only.

Alternatively, you can extend com.adobe.cq.dialogconversion.AbstractDialogRewriteRule as below. The abstract class implements the getRanking method and uses the service.ranking OSGi property of the service to determine the ranking of the rule.

@Component
@Service
@Properties({
        @Property(name="service.ranking", intValue = 10)
})
public class CustomDialogRewriteRule extends AbstractDialogRewriteRule {
 
 
    public boolean matches(Node root) throws RepositoryException {
        // ...
    }
 
    public Node applyTo(Node root, Set<Node> finalNodes) throws RewriteException, RepositoryException {
        // ...
    }
 
}
        

Code samples are intended for illustration purposes only.

Sample Rewrite Rules

Code on GitHub

You can find the code of this page on GitHub

Any questions?

Have a question about this or any other AEM topic? Ask our Community.
Learn more about AEM topics on our help hub.
Was this helpful?

By submitting your feedback, you accept the Adobe Terms of Use.

Thank you for submitting your feedback.