Prohlížíte obsah nápovědy pro verzi:
- 6.4
- 6.3
- 6.2
- Starší verze
The dialog conversion tool is provided to help extend existing components that only have a dialog defined for the classic UI (based on ExtJS) or based on Granite UI and Coral 2. The tool uses the original dialog to create a duplicate dialog designed for the standard UI, based on Granite UI and Coral 3.
The goal of this tool is to automate the upgrade as far as possible, increase efficiency, and reduce errors. However because the tool can not cover every scenario, the process can not be fully automated and the user must review the converted dialogs and possibly make additional adjustments. The tool is intended as an aid to help you start the conversion process, but not intended to take full control of the conversion.
The tool will create the new dialog using the standard, Granite UI and Coral 3-based UI, but it will skip what it cannot convert. Therefore the resulting dialog might contain nodes from the original dialog copied as-is, if no rule matched that specific component. In addition, a converted component might have some unconverted properties, because there was no appropriate rule to convert them.
Pozor:
The tool cannot cover every scenario, as its conversion rules are non-exhaustive and operate on a best-effort basis. It converts the most frequently used elements and properties, but the conversion will be incomplete when dealing with customizations or highly-specialized dialogs. Converted dialogs may require additional adjustments and all conversions must be reviewed.
Poznámka:
Because the classic UI is no longer being developed or enhanced, Adobe recommends that customers upgrade to the default Granite UI user interface to benefit from the latest technology.
Although it is generally good practice to migrate to the latest platform, migrating from Coral 2 to Coral 3 is not critical. However any new project should be started based on Coral 3.
CODE ON GITHUB
You can find the code of this page on GitHub
- Open aem-dialog-conversion project on GitHub
- Download the project as a ZIP file
Poznámka:
AEM does not ship with the dialog conversion tool. You must download and install it in order to use it.
-
Download the package from the Dialog Conversion Tool GitHub project.
-
Install the package on your instance. For details on package management see How to Work With Packages.
The tool converts dialogs by creating a corresponding Granite UI / Coral 3 dialog at the same location as the original dialog in the content tree. In the case of Granite UI / Coral 2 dialogs, these are copied to a backup location (a .coral2 suffix is appended to the dialog node name) so as not to be overridden. The tool can convert design dialogs as well as edit dialogs.
-
The table lists all existing legacy dialogs below the entered path. Each dialog has its Type listed. Types include:
- Classic: Nodes of type cq:Dialog that have node name dialog or design_dialog
- Coral 2: Nodes named cq:dialog or cq:design_dialog that have a Granite UI / Coral 2 resource type at their child content node
Each row contains a link to view the dialog and a link to CRXDE Lite to view its node structure.
Poznámka:
Components that do not have a dialog for the classic UI or Coral 2 at all (i.e. they designed with Granite UI / Coral 3) are not listed.
The dialog conversion tool is based on the concept of graph rewriting, consisting of transforming a subject graph by applying rewrite rules. A rewrite rule is the pairing of a pattern with a replacement graph. The rule matches occurrences of a certain subgraph in the subject graph and subsequently replaces them. See also http://en.wikipedia.org/wiki/Graph_rewriting for details on graph rewriting.
The dialog conversion tool uses this approach to rewrite a given legacy dialog tree (Classic or Granite UI / Coral 2) to its Granite UI / Coral 3 counterpart. This has the advantage that the conversion is highly flexible and can take into account even complex components, since matching is done on actual subtrees and not only single nodes or properties.
The rewrite algorithm takes as a parameter the tree to be rewritten and a set of rewrite rules. It traverses the tree in pre-order and for each node checks if a rule applies for the subtree rooted at that node. The first rule that matches is applied to that subtree in order to rewrite it. The traversal then restarts from the root. The algorithm stops as soon as the whole tree has been traversed and no rule has matched any subtree. As an optimization measure, the algorithm keeps track of a set of nodes that are final and therefore don't have to be rechecked for matches in subsequent traversals. It is up to the rewrite rules to define which nodes of the rewritten tree are final, and which should be revisited by future passes of the algorithm.
The entry point for the conversion is the DialogConversionServlet, which is registered on POST requests to /libs/cq/dialogconversion/content/convert.json. It accepts a path request parameter, which is an array containing the paths to the dialogs that should be converted. For each dialog, the servlet then rewrites the corresponding dialog tree by applying all defined dialog rewrite rules.
The rewrite rules can be defined in two different ways, either as:
- JCR node structures - Node-Based Rewrite Rules
- Java classes implementing a specific interface - Java-Based Rewrite Rules
Some are provided out-of-the-box, but you can also define your own customized rules. Sample rewrite rules are also available.
Typically, a single dialog rewrite rule is responsible for rewriting a single dialog element, for example the pathbrowser input field.
Pozor:
Rewrite loops are not detected by the algorithm, therefore rewrite rules must not rewrite trees in a circular fashion.
rule - jcr:primaryType = nt:unstructured - cq:rewriteRanking = 4 + patterns - jcr:primaryType = nt:unstructured + foo - ... + ... + foo1 - ... + ... + replacement + bar - ... + ...
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 match. In order for a pattern to match, the subject tree must contain the same nodes as the pattern (matching names) and all properties defined in the pattern must match the properties of the tree.
In the case of a match, the matched subtree (called the 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. Alternatively, a default value can be specified for that case (only possible for string properties):
${<path>:<default>}
Properties that contain ':' characters can be single quoted to avoid conflict with providing a default value. Boolean properties are negated if the expression is prefixed with '!'. Mapped properties can be multivalued, in which case they will be assigned the value of the first property that exists in the matched tree.
For example, the following property one will be assigned the value of the property ./two/three of the matched original tree.
... + replacement + bar - one = ${./two/three} - negated = !${./some/boolean/prop} - default = ${./some/prop:default} - multi = [${./prop1}, ${./prop2}]
Rules also support the following optional properties.
cq:rewriteOptional (boolean)
Set this property on a pattern node to indicate that the node doesn’t have to be present for the pattern to matchcq:rewriteRanking (integer)
Set this property on the rule node to affect the order by which the rules are applied. This can be useful in ensuring that rules handling more specific structures aren’t overwritten by more general ones. Rules with a lower ranking take precedence over those with higher ranking. All rules by default receive Integer.MAX_VALUE as their ranking.
The replacement tree also supports the following special properties (named beginning with cq:rewrite):
cq:rewriteMapChildren (string)
The node containing this property will receive a copy of the children of the node in the original tree referenced by the property value (e.g. cq:rewriteMapChildren=./items).cq:rewriteFinal (boolean)
This is an optimization measure telling the algorithm that the node containing this property is final and doesn't have to be rechecked for matching rewrite rules. When placed on the replacement node itself, the whole replacement tree is considered final.cq:rewriteCommonAttrs (boolean)
Set this property on the replacement node (rule/replacement) to map relevant properties of the original root node to Granite common attribute equivalents in the copy root. It will handle data attributes by copying/creating the granite:data subnode on the target and writing data-* properties there.- cq:rewriteRenderCondition (boolean)
Set this property on the replacement node (rule/replacement) to copy any Granite render condition (rendercondition or granite:rendercondition) child node from the original root node to a granite:rendercondition child of the copy root.
In addition, a cq:rewriteProperties node can be added to a replacement node to define string rewrites for mapped properties in the result. The node is removed from the replacement. The properties of the cq:rewriteProperties node must be named the same as those which they are rewriting and accept a string array with two parameters:
- pattern: Regex to match against, e.g. "(?:coral-Icon–)(.+)"
- replacement: Provided to the matcher replaceAll function, e.g. "$1"
The following is an example of rewriting Coral 2 icon properties to Coral 3 equivalents:
... + replacement + bar - icon = ${./icon} + cq:rewriteProperties - icon = [(?:coral-Icon--)(.+), $1]
The rewrite rules provided are defined at:
/libs/cq/dialogconversion/rules
The rules are further divided at this location into folders for classic rewrite rules and Coral 2 rewrite rules:
/libs/cq/dialogconversion/rules/classic
/libs/cq/dialogconversion/rules/coral2
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.
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();
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.
For further information see the Javadocs for com.adobe.cq.dialogconversion.
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() { // ... } }
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 { // ... } }
The cq-dialog-conversion-content package contains several predefined rewrite rules. For classic UI widgets see Using xtypes for more information).
Rule | Legacy Component | Granite UI / Coral 3 Replacement |
com.adobe.cq.dialogconversion.rules.CqDialogRewriteRule | Node of type cq:Dialog, handles different substructures | A granite/ui/components/foundation/container using either a fixedcolumns or tabs layout The actual components of the dialog are copied over and are rewritten in subsequent passes of the algorithm. |
com.adobe.cq.dialogconversion.rules.IncludeRule | xtype = cqinclude | The referenced node is copied to the Granite UI / Coral 3 dialog and (possibly) subsequently rewritten by the algorithm. |
com.adobe.cq.dialogconversion.rules.MultifieldRewriteRule | xtype = multifield | A granite/ui/components/coral/foundation/form/multifield The fieldConfig child node (if any) is rewritten separately, thus not limiting the supported components. |
/libs/cq/dialogconversion/rules/classic | button checkbox colorfield combobox componentselector datetime fieldset fileupload hidden numberfield panel password pathfield radio radiogroup select sizefield tabpanel tags textarea textfield |
|
/libs/cq/dialogconversion/rules/coral2 | actionfield autocomplete button checkbox collapsible colorpicker container datepicker fieldset fileupload fixedcolumns heading hidden hyperlink include multifield nestedcheckboxlist nestedcheckboxlist-checkbox numberfield password pathbrowser radio radiogroup reset select submit switch tabs tags text textarea textfield userpicker well |
CODE ON GITHUB
You can find the code of this page on GitHub
- Open aem-touchui-dialogconversion-samples project on GitHub
- Download the project as a ZIP file