Pages

Monday, December 24, 2012

cq5 - eclipse - monitoring when something goes wrong in the eclipse IDE

The Problem

Something strange is going on when running the Eclipse IDE, and you want to get a clue as to what the problem may be.

The Solution

Go to your eclipse directory, where your eclipse.exe file is, and run the following command:

eclipse.exe -Dcom.sun.management.jmxremote

This will run your eclipse IDE in debug mode.

Then go to your Java home directory in your sdk, ie, C:\Program Files\Java\jdk1.6.0

Note, if Java has been configured correctly, you can use:
echo %JAVA_HOME%

on the command line to see which directory is being used

go to the bin directory in your java home, and run jconsole.exe

Connect to your process ID, and you can profile eclipse to get an idea of what is going on.

CQ5 with eclipse - forever indexing maven

The Problem

When opening Eclipse, Maven is stuck on indexing, unsuccessfully and indefinitely attempting to update its indexes.

The Solution

The mvn index needs to be disabled on startup, by launching eclipse, and immediately going to:
Window -> Preferences -> Maven -> Download repository index updates on startup.

Thursday, December 13, 2012

No code complete in CRXDE

The Problem

In CQ5.5 SP1, CRXDE does not have code complete, classes can't be found, laptop is in serious risk of defenestration.

The Solution

Go to Package Share in CQ5 admin on author.

http://localhost:4502/crx/packageshare/

Log in if required with your adobe id.

Click on Download for:
1. Missing CRXDE-Libs
2. CRX Hotfix Pack

And install these packages.

Restart CQ5 and CRXDE, and hopefully this will have resolved the issue.

Wednesday, December 12, 2012

Formatting JSON

I was writing a SlingServlet that was to output JSON, and I wanted a neat tool to format my request.

I used notepad++ combined with the JSMin plugin.

To install JSMin,
1. open notepad++
2. Click on Plugins->Plugin Manager-> Show Plugin Manager
3. Scroll down to JSMin, click on the checkbox and install

Now just copy and paste your raw JSON in, and to format, press Ctrl+Alt+M, or go to Plugins->JSMin->JSFormat


Tuesday, December 11, 2012

gotchya - cq 5.5 doesn't work properly with JRE 1.7

I had upgraded my laptop, gleefully installed CQ5.5, and promptly was pulling tufts of hair out.

Custom Sling Servlets weren't behaving, and I was getting general issues with my CQ instance. What the dickens is going on?

Well.... I had JRE 1.7 installed, not 1.6.14

http://dev.day.com/docs/en/cq/current/deploying/technical_requirements.html


Java Virtual Machines

CQ5 operates with the following versions of the Java Virtual Machine (Runtime Environment).
Platform Support Level
Oracle JRE 1.7.x A: Supported with CQ 5.5 SP2 or newer
Oracle JRE 1.6.x A: Supported
Oracle JRE 1.5.x D: Validated
Oracle JRE 1.4.2 Z: Not supported
IBM JRE 1.6 A: Supported
IBM JRE 1.5 D: Validated
HP JRE 1.5 E: Expected to work


So there are 2 options.

1. Upgrade to SP2
2. Downgrade the JRE to 1.6.14

After I had downgraded the JRE and restarted, things returned to normal again.

If someone upgrades to SP2 experiencing similar issues, please comment below.

Wednesday, December 5, 2012

Running and debugging CQ5 using CRXDE

The Problem

You want to debug your code on a CQ5 server using Breakpoints in CRXDE, but the Debug option is greyed out.

The Solution

Chances are, you are not running CQ5 in debug mode. Here is a simple way to start your CQ5 instance in debug mode, and how to attach CRXDE to it.

Assuming a windows machine and a local copy of CQ5 for the purposes of this tutorial, located at c:\cq5\author running on the default port 4502.

1. Ensure that all local instances of CQ5 are shut down.

2. Under windows. open up command from the start menu, navigate to the c:\cq5\author directory

3. copy and paste the following command:

java -debug -XX:MaxPermSize=256M -Xnoagent -Xmx1024M -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=30303 -jar cq5-author-4502.jar -nofork

4. IMPORTANT: It can take quite a while for the server to start in debug mode. Wait until your browser window opens up at the author login screen before continuing.

5. Open up CRXDE. Search for it in your supplied CQ5 materials.

6. Enter http://localhost:4502 in the URL field, and admin/admin for the username and password.

7. Click on OK, and wait for CRXDE to load.

8. To test, we can navigate to a piece of code that you can break into.

A good place to test is to put a breakpoint on line 31 in /apps/geometrix/components/title/title.jsp

When you have put the breakpoint in, navigate to:
http://localhost:4502/cf#/content/geometrixx/en/products.html

You will now be able to step through your code.

Gotchyas


Thursday, November 1, 2012

The Fine Art of Minification in CQ5.5

The Problem:

Pages are taking too long to load in production, because the JavaScript pages contain comments, whitespaces and long variable names causing bloating in file size.

The Solution:

Minification! What is minification you ask?

The Theory:

In a nutshell, minification is a fancy term for getting rid of unnecessary characters in your JavaScript. It is a subset of obfuscation.

Minification in CQ5 does the following:
  1. Removes the following superfluous characters from the JavaScript code:
    1. White Space Characters
    2. New Line Characters
    3. Comments  
  2. Renames long variable and function names in the local namespace to something smaller
You need to be careful to note that if you have ridiculously long function names, you will still wind up with bloated JavaScript files, as the Minification engine in CQ5 does not yet 


The Implementation:

To activate minification, you will need to log in to your Felix console and enable the minify option.

  1. Go to {ServerURL}/system/console/configMgr
  2. Scroll down and click on "Day CQ HTML Library Manager"
  3. Click on the Minify checkbox
  4. (Optional) Enable Gzip

Where to Next?

If minification does not reduce your file size enough yet, you only have a few options. If you can think of more, please let me know so that we can collate them here.

1. Refactor your unnecessarily loquacious  names to more simple and understandable names. (Coming Soon: Link to post on how to get understandable names.)

2. Use an external JavaScript minifier such as http://closure-compiler.appspot.com/home
NOTE: If anyone out there thinks there is a better minifier, please comment below.

3. See if you can hang your code out to DRY

Customizing DAM image metadata

The Problem:

You have a CQ site that needs additional metadata globally attached to your images within the DAM.

The Solution:

The Theory:

Extend the DAM to capture the required information.

If you add a folder and image into the DAM, you are creating a JCR node with a binary blob attached, and whole slew of additional metadata.

As an exercise, go into the dam, create a new folder called /content/dam/TestPicture, and add any jpg image called TestJPG.jpg.

Go to your crx explorer by visiting localhost:4502/crx/explorer/browser/index.jsp, and navigate to content/dam/TestPicture

If you have added the image previously, you will find a dam:Asset node titled TestJPG.jpg.

If you expand this node, the jcr:content node and then click on metadata, you will see a list of the current metadata associated with the image.

Go back to the DAM, and double click on the TestJPG.jpg image, and you should see a properties popup, allowing you to enter a list of metadata to associate with the image.

Enter Test Title into the title field, and make the language English.

Go back to the crx explorer, click on jcr:content and back on metadata. This will refresh the list. You will see that dc:language is set to English, and dc:title is set to Test Title.

If you have done the Retrieve Data from JCR recipe (Coming Soon), you will see that you can retrieve this metadata freely from the JCR.

The implementation:

This is great if you only want to capture the information provided by default, but what if you want your application to have additional data, such as a clickable link for the picture, or phone and email details? 

What needs to happen, is you need to customise the DAM editor.

If you look into libs/dam/content/asseteditors/image/jpeg/formitems, you'll see that the list of nodes here is the list of items in the JPG image metadata properties page.

Now, you *could* just add new custom nodes here and end the tutorial, but this is definitely not a good thing to do, as you want to leave the libs folder alone.

Instead, you'll want to create a new folder structure down to /apps/dam/content/asseteditors/image, right click on the libs/dam/content/asseteditors/image/jpeg folder and click on copy, navigate to your newly created /apps/dam/content/asseteditors/image folder, and click on open.

Sling will render the apps/dam/...etc content before the libs/dam/...etc content if it exist, and you won't be messing around with the internals of CQ5.

OK, now let's say after the description, we want to add a new field called clickURL

Go to /apps/dam/content/asseteditors/image/jpeg/formitems in the crx/explorer, right click and select New Node. For the name, enter clickURL, and for the type, select cq:Widget from the dropdown. Left Click on the newly minted node, and double click on title. Enter Click URL.
Double click on xtype, and enter textfield.
for the name, enter ./dc:clickURL..

Go back to the TestJPG.jpg in the dam, double click on it, and you should see the new field.

Enter www.google.com for the clickURL, Click on the save button down the bottom right.

If you now look at the metadata for the image in the crx/explorer, you'll see a dc:clickURL property, populated with www.google.com.

Note that if you don't fill in the information, the property is not created in the metadata.

Repeat the same process to create a new node for Person Name using personName as the name, and Location Address using locationAddress the name, both as text fields.

Go back to the dam, double click on the TestJPG.jpg again, and you will also see the new fields present.

Let's create two sub folders in TestPicture, content/dam/TestPicture/personnel and content/dam/TestPicture/locations.

Copy in a random JPG file called johnbrown.jpg and a random JPG called 123AnywhereSt.jpg.

Double click on johnbrown.jpg, and notice that you can now enter John Brown into the Person Name field.

Double click on 123AnywhereSt.jpg, and you can enter 123 Anywhere St into the Location Address field.

The problem here, is that you are now prompted anywhere in the DAM with the ability to label an image with Person Name and Location Address details. In this case, the Location Address should not show in the content/dam/TestPicture/personnel folder, and Person Name should not show in content/dam/TestPicture/locations.

Fear not, there is an answer. You can use a node listener to allow sling to determine whether the node should be shown or not, based upon the originating location of the folder.

You add a listener by navigating to the /apps/dam/content/asseteditors/image/jpeg/formitems/personName node in the crx/explorer, right clicking, and adding an nt:unstructured node called listeners. Right click on the listeners node, and select New Property, and call it beforeloadcontent. Leave it as a String property. Now for the magic.

Set the beforeloadcontent parameter to the following:
function(f, r, p) { if (p.indexOf("/content/dam/TestPicture/personnel") != 0) { f.hide(); } return true; }

Let's look at this in detail. First of all our function signature: function(f, r, p).

f stands for the field, r for the record, and p for the path.

The if statement ( if (p.indexOf("/content/dam/TestPicture/personnel") != 0) ) checks to see if the path of the folder we are working in matches with the listener. You can vary this logic however you may need to, but in our case, we want all of our images down from folders in personnel to show the personName field.

Click on save, go back to the DAM, and double click on the /content/dam/TestPicture/personnel/johnbrown.jpg file. You'll see that the Person Name field is still displayed.

Double click on content/dam/TestPicture/locations/123AnywhereSt.jpg file, and you'll see that PersonName is not there as a field.

Repeat the same process for the content/dam/TestPicture/locations path by repeating the above steps, but this time pasting the following line into the beforeloadcontent parameter:
function(f, r, p) { if (p.indexOf("/content/dam/TestPicture/locations") != 0) { f.hide(); } return true; }

You can repeat this process as needed.

Where to Next?

You can use a wide selection of widgets within the editors, such as date pickers, combo boxes, checkboxes. You can see a selection of components by visiting:

Navigate to CQ/Ext/form, and you'll see quite a few form field components. To use them, find the component you want, and declare it with the xtype variable instead of  using textfield. For example, if you wanted a checkbox, set the xtype variable to checkbox.


You can also Restrict Folders by User Using the ACL list (Coming Soon)