Setting default values on CQ components

Components are self-contained portions of code within CQ. While not necessarily visual or part of the user interface, oftentimes they are. Within the CQ framework components can be dragged from the SideKick and placed within a page layout.

Within the CQ page editor, a component can have a dialog to configure values for the component instance that is on the page. Documentation exists that describes how to create a component for use within CQ. It is not necessary for the page author to open the component editor and edit all of the values each time a component is used. Properties can be defined with a default value which is applied automatically.

Prerequisites

To create a default value on a component, knowledge of how to create and edit components within CRXDE or CRXDE Lite is necessary.

Setting a default value on a CQ component

Go to the widget within the component’s dialog that is used to set the property on the component and add a property to the widget itself: defaultValue. If it is possible to select multiple values the defaultValue property should be an array.

Example

In this example I will have a simple viewer component that has a single configurable property: alignProp. Alignment may either be a Left or Right. By default, the value should be Left.

Within the /apps/dekesmith/examples/components/ directory I created a new component node called simple-viewer:

{
    " jcr:title":"Simple Viewer",
     "allowedParents":["*/*parsys"],
     "sling:resourceSuperType":"foundation/components/parbase",
     "componentGroup":"Media",
     "jcr:primaryType":"cq:Component",
     "dialog":{
          "jcr:primaryType":"cq:Dialog",
          "items":{
               "jcr:primaryType":"cq:WidgetCollection"
               "items":{
                    "jcr:primaryType":"cq:WidgetCollection",
                    "tab1":{
                        "jcr:primaryType":"cq:Panel",
                        "title":"tab1",
                        "items":{
                            "jcr:primaryType":"cq:WidgetCollection",
                            "alignment":{
                                  "jcr:primaryType":"cq:Widget",
                                  "fieldLabel":"Alignment",
                                  "type":"select",
                                  "xtype":"selection",
                                  "defaultValue:","Left",
                                  "name":"alignProp",
                                  "options":{
                                       "jcr:primaryType":"cq:WidgetCollection",
                                       "Left":{
                                            "jcr:primaryType":"nt:unstructured",
                                            "value":"Left",
                                            "text":"Align Left"    
                                       },
                                       "Right":{
                                            "jcr:primaryType":"nt:unstructured",
                                            "value":"Right",
                                            "text":"Align Right"
                                       }
                                  }
                            }
                        }               
                    } 
                }
          }
     }
}
 

This component has an edit dialog for setting properties of the component within the CQ site editor. The edit dialog has a single tab with a single selection menu, alignment, that sets a property for the component, alignProp. The alignment menu has two choices, Right and Left. The default value should for the property should be added on the widget that sets that property. To give the alignProp property a default of Left I added a defaultValue to the selection widget, alignment.

Using sling:Mapping to expose repository values

Besides conventional client access to Web sites using a browser, client applications can be built within applications such as Flex and still access data in our repositories. A quick way of doing this is by having Flex access that data as JSON. There is one thing that makes this problematic for production. When a publish instance is accessed through Dispatcher it is suggested that any access to URLs ending with the .json suffix should be forbidden. For security reasons many directories in the repository should not be accessible through outward facing connections. Like I mentioned, this can be problematic if JSON is being accessed by Flex.

Sling, and by extension CQ, has a redirect mechanism that can selectively expose values.

Pre-requisites

Knowledge of the use of CRXDE or CRXDE Lite to edit nodes and properties is required for the example.

What are sling:Mapping nodes?

Sling uses sling:Mapping nodes much the same way that Apache’s mod redirect uses its configurations in httpd to define redirect behavior. The Apache Sling Web site has documentation for mappings. Existing mappings can be seen in the Sling Resource Resolver Console at http://[host]:[port]/system/console/jcrresolver.

A brief explanation is that redirect behavior can be configured by setting properties on sling:Mapping nodes. There should be one sling:Mapping node per redirect rule. The sling:Mapping nodes can have nested sling:Mapping nodes, but that is not needed for my simple example and I won’t go there at this time. Add the sling:Mapping nodes to the repository within the /etc/map/ directory. Sub-folders can be created in this directory and that has an effect on how URLs are matched for redirecting. Once again, this article does not need this and I won’t get into that. This framework can be very powerful and has many ways of being configured. The use case for the sling:Mapping node will be basic and simple in this example.

Using redirection to access JSON data behind a securely configured Dispatcher

For this example I will show how to create a redirect that allows access to the possible values of a dialog used to configure a component. The component is the Flash component. The values are for the menu property of the Flash component. That value is contained within the dialog configuration of the Flash component:

|- libs
   |- foundation
      |- components
         |- flash
            |- dialog
               |- items
                  |- menu
                     |- options
 

The url I used to get the JSON version of this on my local, sample server is [1]. Calling this JSON as admin returns:

{
     "jcr:primaryType":"cq:WidgetCollection",
     "show":{
          "value":"show",
          "jcr:primaryType":"nt:unstructured",
          "text":"Show"
     },
     "hide":{
          "value":"hide",
          "jcr:primaryType":"nt:unstructured",
          "text":"Hide"
     }
}
 

The direct URL to this value is not available behind Dispatcher. Dispatcher should not allow calls either to the /libs directory nor any resource with a .json suffix.

To make it so the Flex client can query this value we need to set up a mapping for it.

  1. Create a node called, menudata, of type sling:Mapping within the /etc/maps/ directory
  2. Create a property called, sling:internalRedirect, of type String to the menudata node. Set it to:/libs/foundation/components/flash/dialog/items/advanced/items/menu/options.1.json
  3.  Create a property called, sling:match, of type String to the menudata node. Set it to:^[^/]+/[^/]+/menu-options$

Once saved, the redirect takes effect. You should see the values of this mapping if you go to Sling Resource Resolver Console.

The sling:internalRedirect property is the relative URL to a resource within the repository. There are, of course, exceptions. But for this example the value of the internalRedirect property is returned without sending a redirect message back to the browser.

The sling:match property is a regular expression pattern used to match the URL. If this property were not present in the sling:Mapping node it would use the node’s name to match with.

Now, when I go to the URL that calls menu-option ([2] on my local server), the value of the options node is returned.

Standard cautions apply. Be very conservative about what you expose to the outside world. But the redirect mechanism in Sling is very powerful and it is worth exploring.

[1] http://localhost:4502/libs/foundation/components/flash/dialog/items/advanced/items/menu/options.1.json

[2] http://localhost:4502/menu-options

Creating images from PDFs that are proportionally the same size in LiveCycle ES2 and ES3

Problem:

What if images produced from PDFs within the timeline of LiveCycle need to all be the same size? PDFs that are the same size, dimension-wise, can turn out as images of different sizes after processing with the toImage activity. For example, two PDFs could be 8.5 x 11 inches in size. But one would convert to an image that is 1700 x 2200 pixels in size and the other would convert to an image that is 2550 x 3300 pixels in size.

Resolution:

Use the same DPI argument for each of the PDFs. The resulting images will not be an exact match with one another, however. In my test a variation of ten pixels or so could be seen as the result of differences in the areas of the PDF page that are converted to image. But PDFs that are the same dimensions before conversions result in images that are the same pixel height and width (or very close to it).

See Also:

The documentation for the toImage operation of the Convert PDF service

Editing the content directory in CRXDE

CRXDE is the eclipsed-based tool used to to develop within the CQ and CRX repository. By default, only a few directories within the repository are visible. The content directory is not one of them. A setting in the repository must be change before it can be seen.

Go to /etc/crxde/profiles/default. There is a property, crxde:paths. This property is a list of String. Add /content to that list and restart CRXDE.

Output Exceptions in CQ Blog Feeds

Symptom

The Atom blog feed from CQ that is obtained by using the .feed suffix on a URL has exceptions within it. The output is an error witinh the feed.jsp or feedentry.jsp file and it contains the following:

Caused by: java.lang.IllegalStateException: output stream already obtained
 

What Can Be Done?

There is a structural supposition within CQ that the output of JSP pages will be HMTL. Because of that, <div> tags are generated for sections of content automatically. Writing these <div> tags causes writes to the output buffer that should not happen. Even if writing to the output buffer did not cause the exception, it would create bad Atom files with <div> tags sprinkled throughout in places they should not be. Changes need to be made to the JSP pages that handle the *.feed suffix. Those files can be found here:

/libs/foundation/components/page/feed.jsp /libs/foundation/components/page/feedentry.jsp /libs/collab/blog/components/page/feed.jsp /libs/collab/blog/components/page/feedentry.jsp

Within ALL feed oriented JSP files (*.feed.jsp, *.feedentry.jsp, etc) the following must be added:

// This bypasses the normal component handling with its automatic output of content
request.setAttribute(ComponentContext.BYPASS_COMPONENT_HANDLING_ON_INCLUDE_ATTRIBUTE, "true");

// This changes the tag used for blocking areas of content from "div" to "". 
// When empty, a tag will not be written to create blocks of content.
IncludeOptions.getOptions(request,true).setDecorationTagName("");

These nodes are part of the foundation components for CQ. Make backups. And be aware that these components can be overwritten without warning in future updates. You will need to document well the changes that have been made in case problems arise later.

Watched File System Folders in CQ/CRX

Greg Klebus suggested using WebDAV to mount repository directories on the file system. Doing this, he said, the end user has access to file system directories on which CQ can automatically run workflows.

A quick example of this is mounting the DAM directory as WebDAV. When content is added or changed within the DAM directory of CQ, a workflow process will run automatically.

These are the steps I go through for using WebDAV with Windows 7 to do that very thing.

I mount the CRX repository as a mapped drive within Windows 7 by right-clicking on the computer and selecting the Map Network Drive menu item. I pick the drive letter and, for my local installation, use the CRX WebDAV URL for my server [1].

Windows 7, out of the box, may not support WebDAV. To use WebDAV on a computer with Windows 7 you may need to install an update from Microsoft: Software Update for Web Folders [2]. You may want to see if it works without this update. It is an old software update and only lists Windows 2003 and Vista specifically. For instructions on how to get Windows 7 64bit, specifically, to work with WebDAV go to [3].

Within CQ 5.4, you can set the permissions of a directory under /var/dam to allow read/write or write privileges for the end user. When they drop an image into this folder there is a workflow that explodes the image, generates thumbnails, and creates the dam:asset for that image. The result of the process can be seen in the /content/dam directory. For CQ 5.5, images placed into /content/dam and its sub-directories will trigger the workflow.

[1] http://localhost:4502/crx/repository/crx.default

[2] http://www.microsoft.com/en-us/download/details.aspx?id=15123

[3] http://shon.org/blog/2010/03/04/howto-fix-windows-7-64bit-webdav/

Appliness Digital Magazine

A new digital magazine has been released that is aimed towards HTML developers. It is called Appliness. It is downloadable for both Android and iOS from each platforms respective market. Links to the more information about this magazine and a description of how it is put together can be found at  Michaël Chaize’s blog.

Register a Custom Namespace within CQ

It is possible to add your own namespaces within CQ. Just as there are predefined namespaces such as cq, jcr and sling, you can have a namespace for your repository metadata and xml processing.

Go to the node type administration page, http://<host>:<port>/crx/explorer/nodetypes/index.jsp. The right-most button at the top of this pages is Namespaces. Clicking that button will open a pop-up window containing the namespace administration page. At the bottom of the page is the New button use to add a namespace.

The namespace follows the XML namespace convention. There is the id in the form of a URI and the prefix associated with that id.

What is the gray circle with an exclamation mark (or bang)?

[Note: edited 7 Jun 2012, 13 Aug 2012 to make changes based on comments that have been received]

The generic memory error icon was added in Flash Player version 10.1 and will appear within a browser when the Flash Player has been particularly abused or is running in a very low memory environment. The icon, affectionately known as the Gray Circle of Death (GCOD), is a gray circle with a white exclamation mark within it.

It is not just an icon, however. It is a sign that Flash is protecting your computer from an application that is asking for more memory than your browser has available. The browser will crash if it runs out of memory and that is a Very Bad Thing. If that happens your browser may crash or your computer may crash and need a restart. Flash now has the feature in which it shuts down an application if that application causes a memory problem.

Note: One recurring comment to this post is that one application or another created in Flash often triggers this icon to appear. “Why don’t you fix Flash?” The answer to that question is that Flash is doing exactly what it is supposed to do. It is protecting your computer.

It is possible in Flash, as with most programming languages, to create create an application that doesn’t play nice.

The Flash Player tries to shield the user from either intentional or unintentional mischief that an application can create. The GCOD is shown when Flash has stepped in and kept an application running in the Flash Player from using more memory than is available. The Flash Player stops execution of an application and displays the GCOD when an application requires more memory to continue running than is available.

It is important to point out that the Flash Player has not overrun its available memory. If it had Very Bad Things would have occurred. What did happen is that Flash Player yanked the leash of an application and shut it down when it needed more memory than the browser had available.

For that reason, the GCOD is a very good feature of the Flash Player.

Getting Rid of the GCOD

Most important to most people is not what the GCOD is, but how to make it go away. In all cases, an application does not have enough memory to run. The application could be needing a reasonable amount of memory but the browser does not have that much memory available. On the other hand, the application could also go into a death spiral because of a programming error and suck up every bit of memory available in even the heftiest computers. There are many ways for an application to overrun its memory.

When the GCOD is seen, the first course of action is to contact the developer of the Flash application. I have a decent computer and I have only seen the GCOD appear because of the coding of the application. The GCOD is not a problem Flash Player causes. You see it when the safety valve has blown.

For more:
Flash Player 11 Technical Specifications
Garbage collection internals for Flash Player and Adobe AIR
Optimizing Performance for the Adobe Flash Platform

True literacy in the 21st Century

“The illiterate of the 21st century will not be those who cannot read and write, but those who cannot learn, unlearn, and relearn.”

Alvin Toffler