Skip to content

Posts tagged ‘CQ’

9
Mar

CQ5 Workflows: Selection Dialog

Since a few years I am working with Adobe CQ (formerly Day CQ) doing mostly backend software like ETC Mapping, Link Rewriting, Dispatcher Cache handling, OSGi Services and mostly Workflows. About 1 1/2 years ago I did not know how the Workflows worked in CQ and now I am even adding additional functionality like a Dialog and Dynamic Participant Step.

Here I want to talk about how to provide a drop down box selection in a Workflow Dialog Participant Step. In order to make that work we need three parts:

  1. Servlet / JSP that provides an JSon Array with ‘text’ / ‘value’ pair
  2. Dialog Definition that contains the Drop Down Box
  3. Dialog Participant Step using the Dialog Definition

Attention: There is a bug in the display of an embedded Dialog where the labels of the dialog are ignored. This is pretty annoying but the Workflow designer can add a hint into the title to make it clear what the fields are.

This is how the dialog will look like inside the Workflow Inbox:

CQ5 Workflow Dialog Selection Dynamic

Read more »

28
Mar

CQ 5.4 / 5.5 Resource Mapping


Introduction

Several times I ran into Resource Mapping inside CQ / WBEM and had issues with it over and over again. Now I had to go into it and make it work and this is the result of it.

There were a few issues that need to be handled in order to avoid a lot of grief and there are a few things that can be done in order to make life easier.

Resource Mapping

CQ is able to map resources on an incoming request as well as on the outgoing result. For example if your resource is /content/geometrixx/en/products.html and you map it to /en/products.html then CQ will show it with /en/products.html (obviously) but it also maps a link inside another page when the page is sent to the browser.
This means that one has to be careful when mapping resources because CQ will map them no matter what and you must be especially careful when dealing with the Author instance.

Map the Root

Here I assume we are working inside CRXDE|Lite on the Publish instance. Now we want to map http://testme.com:4502/ to /content/geometrixx/de.html. This is what you need to do:

  • Open the hosts file (Mac/Unix: /etc/hosts) and add row with 127.0.0.1 testme.com and make sure with ping testme.com that is resolves to 127.0.0.1
  • Go to the Node /etc/map/http
  • Right-click and select Create Node
  • Enter name testme_com with the type sling:Mapping
  • Go to the Properties of the newly created node
  • Add a new Property with name sling:match and value testme\.com.4502
  • Add a new Property with name sling:internalRedirect and value /content/geometrixx/de.html
  • Save it with Save All

Now you can open a browser and enter the Url http://testme.com:4504/ and you should see the German Geometrixx site. Now if you click on the Products on the toolbar we are back with the /content/geometrixx/de path.

Dealing with Mapping Issues

Working with Resource Mapping in CQ can be very frustrating depending on the project your are working on. For example the Geometrixx site is a good example what can go wrong but also how to avoid issues like this.
First problem I ran into when mapping resources was that I ended up in an endless loop when trying to map both the English and German pages to different domain names. Because of the browser jumping between various pages I wasn’t able to see what is going on. Eventually I went to the command line (Mac) and used curl to access the web site:

curl http://testgerman:4502

and checked the output. Sure enough the Geometrixx site used the login page fromm the English site and so it would jump to http://testenglish.com:4502, login (on publish it does that automatically as anonymous) and then jump back to http://testegerman.com:4502 where it wasn’t logged in and repeated the loop. Because using curl I could see the source of the desired page and had no endless loop.

Next issue was that even when the page was coming up right it would come up without any images, style sheets etc and using curl again I saw that mapping of elements from /etc won’t work anymore. This means that I had to make sure that certain entries are mapped differently and because the browser accessed the page on the root we had to make sure that we exclude certain entries from the loop.

Map Content

Mapping content is similar to mapping the root but here we can use a trick. If we don’t provide a sling:match property CQ will use the name of the node as a match. So we create it this way:

  • Create a Node with Name testme.com.4502 and type sling:Mapping
  • Add a property with name sling:internalRedirect and value /content/goemetrixx/de
  • Save it with Save All

Now you can open in a browser http://testme.com:4502/products.html and it will bring up the page but without images and style sheets as mentioned above. So we need to make sure that CQ isn’t mapping /etc. This is done this way:

  • Under the node testme.com.4502 we create a child node with name etc and type sling:Mapping
  • Enter a property with name sling:internalRedirect and value /etc
  • Save it with Save All

Because CQ is looking for the longest matching string testme.com:4502/etc is longer than testme.com:4502 and so it will take this one which maps /etc to /etc which is just what we wanted. Now opening http://testme.com:4502/products.html in a browser should come up just fine (you might need to clear the cache).

You can repeat this for other parts of your system like /apps etc if needed.

Still not 100%

Having a closer look at the Products page you will notice that there is no toolbar because it is an URL that maps to /content/geometrixx and not /content/geometrixx/de even though the page starts with de.. This is unfortunate and you might be able to add additional mapping using Regex but then again you are probably not running Geometrixx as your site and so you can make sure that the toolbar etc is inside your CQ context. Unfortunately these shortcomings are not fixed in CQ 5.5. Even worse looking at your page you will find links that start with localhost:4502 even if you CQ instance is running on another port or host.

So it is not 100% but it is close enough for good sites in CQ.

Tips when dealing with Resource Mapping

  1. Resource Mapping is only mapping CQ resources. Don’t try to map anything else.
  2. If a browser gives you grief use curl to see what the server returns
  3. Create a CQ package with the /etc/map as content, delete everything and start step by step. Each step must work as expected before going to the next.
  4. Check the HTML code from the server to verify the results. Browser’s output is often misleading
  5. Make sure that first level folders like /etc, /apps etc are not mapped
  6. To avoid mapping on Author but define the mapping on Author you can create /etc/map.publish instead of /etc/map and then replicate it to the Publish instane(s). Often mapping is not desired inside Author.
  7. If you have problems accessing the CQ Webpage because of the mapping you can use WebDav to remove the mapping nodes.
  8. If you map different domains to different CQ sub folders make sure they are distinct otherwise the mapping of resources inside a returned page is undefined.

Final Result of my Mapping as JSon

curl http://localhost:4502/etc/map.tidy.-1.json

{
  "jcr:createdBy": "system",
  "jcr:created": "Mon Mar 26 2012 19:47:11 GMT-0700",
  "jcr:primaryType": "sling:Folder",
  "testmegerman_com": {
    "jcr:createdBy": "admin",
    "sling:internalRedirect": "/content/geometrixx/de.html",
    "jcr:created": "Wed Mar 28 2012 07:43:42 GMT-0700",
    "jcr:primaryType": "sling:Mapping",
    "sling:match": "testmegerman\.com.4502/$"
  },
  "testmefrench_com": {
    "jcr:createdBy": "admin",
    "sling:internalRedirect": "/content/geometrixx/fr.html",
    "jcr:created": "Wed Mar 28 2012 07:43:42 GMT-0700",
    "jcr:primaryType": "sling:Mapping",
    "sling:match": "testmefrench\.com.4502/$"
  },
  "testmefrench.com.4502": {
    "jcr:createdBy": "admin",
    "jcr:created": "Wed Mar 28 2012 07:43:42 GMT-0700",
    "sling:internalRedirect": "/content/geometrixx/fr",
    "jcr:primaryType": "sling:Mapping",
    "etc": {
      "jcr:createdBy": "admin",
      "sling:internalRedirect": "/etc",
      "jcr:created": "Wed Mar 28 2012 11:10:16 GMT-0700",
      "jcr:primaryType": "sling:Mapping"
    }
  },
  "testmegerman.com.4502": {
    "jcr:createdBy": "admin",
    "jcr:created": "Wed Mar 28 2012 07:43:42 GMT-0700",
    "sling:internalRedirect": "/content/geometrixx/de",
    "jcr:primaryType": "sling:Mapping",
    "etc": {
      "jcr:createdBy": "admin",
      "sling:internalRedirect": "/etc",
      "jcr:created": "Wed Mar 28 2012 11:10:16 GMT-0700",
      "jcr:primaryType": "sling:Mapping"
    }
  }
}