Freitag, 8. Februar 2013

Howto disable upload of CQ5 SmartImage

According to the SmartImage API docs, there is a option to disable the upload of this component.
allowUpload="false"
Unfortunately, it is still possible. I tried to solve it, by preventing the click event. Nothing. I solved it using a CSS workaround, that hides the file upload field. Don't forget to specify the id in both snippets.
<image jcr:primaryType="cq:Widget" allowUpload="false" ddGroups="[media]" height="300" mimeTypes="*.jpg;*.jpeg;*.gif;*.png" mimeTypesDescription="Images" name="./image" hideLabel="true" id="some-unique-id" xtype="smartimage"> // ... </image>
Add this to your css to hide the upload field
/* Hide upload field */ #some-unique-id .x-form-item { display: none!important; }

MySQL Change root Password

Some website, I've seen, recommend
$ mysqladmin -u root -p'oldpassword' password newpass
This is bad, cause all your commands go in plain text straight into your history. Actually you should use
$ mysqladmin -u root -p password
You will be prompted for the old and a new password.

Mittwoch, 6. Februar 2013

Resize an image resource in CQ5 using Java

I already posted the question on stackoverflow, but since I am not allowed yet to post a solution, I'll post it here. I found a quite low level approach, to resizes a image identified by jcrPathToImage to int targetWidth and int targetHeight.

Resize Image

Resource resource = getResourceResolver().getResource(jcrPathToImage); Asset asset = resource.adaptTo(Asset.class); Layer layer = new Layer(asset.getOriginal().getStream()) layer.resize(targetWidth, targetHeight);

Create new rendition in JCR

Extract mime type of the original image
Image image = new Image(resource); String mimeType = image.getMimeType();
Store the resized Image using its asset representation.
ByteArrayOutputStream bout = null; ByteArrayInputStream bin = null; try { bout = new ByteArrayOutputStream(2048); layer.write(mimeType, 1, bout); bin = new ByteArrayInputStream(bout.toByteArray()); asset.addRendition(resizedImgName, bin, mimeType); } finally { // close streams ... }
This may be useful to generate thumbnails.

CQ5 Dialog Validation

By registering a listener to the beforesubmit event, you can validate a dialog.
... xtype="dialog"> <listeners jcr:primaryType="nt:unstructured" beforesubmit="function(dialog){ // your validation code return isValid; }" /> <items jcr:primaryType="cq:TabPanel"> ...

Serverside Validation

After defining a custom validating servlet, you can put the following code snippet in the beforesubmit area. It is important to call the servlet using async=false, to ensure everything is handled by the same thread.
CQ.Ext.Ajax.request({ method: 'POST', url: '/content.myvalidationservlet.json', async: false, success: function(response){ // do something }, params: { ... } });

Email Address Validation using Regular Expressions

Validating email addresses using a pattern is tough and you should evaluate the impacts of using a too weak/strong pattern. On fightingforalostcause.net I found a good comparison of different patterns, that lists all false positives and true positives for the presented regular expressions.

Raw HTML in CQ5

I had to solve a problem of publishing some custom HTML code usning CQ5 with Ext JS. Raw HTML can be passed to DOM using CQ.form.OwnerDraw
var rawComponent = new CQ.form.OwnerDraw({ html: '<div>I am raw</div>' });
To alter this generated code, you may use a wrapping container like
var wrapper = new CQ.Ext.Panel();
and pass the raw component to it.
wrapper.removeAll(); // clear parent wrapper.add(rawComponent); wrapper.doLayout(); // force redraw

CQ.Dialog in JS

CQ5 code exmaples are rare, so i will post some Javascript Code, that would have helped me a lot. CQ5 is shipped with Ext JS.
See API docs for more options.
var dialog = new CQ.Dialog({ 'width': 600, 'modal': true, 'resize': false, 'title': 'My Title', 'items': { 'xtype': 'tabpanel', 'items': [ { 'xtype': 'panel', 'title': 'Basic', 'hideMode': 'offsets', 'items': [ { 'xtype': 'textfield', 'fieldLabel': CQ.I18n.get('app.components.some.key'), }, //... ] } ] }, 'buttons': [ { 'text': 'Save', 'handler': function() { //... } }, { 'text': 'Cancel', 'handler': function () { this.close(); } } ]});

CQ5 Internationalization


To achieve the goal of a multi lingual CQ5-based application, you may use CQ I18n implementation (API) to access the translated strings from the ResourceBundle, according to your language.

In the XML definition of a component, the dialog.xml, use the key directly in the text field, e.g.
fieldLabel="app.component.key"
CQ5 will resolve the reference automatically.

<mypanel jcr:primarytype="cq:Panel" title="app.component.key" name="general"> (...) </mypanel>

In Java Script, CQ5 provides the method
CQ.I18n.get('app.component.key')

In Java we implemented a Localization service, that loads all keys from JCR.
In JSP you can use
<%= I18n.get(slingRequest.getResourceBundle(currentPage.getLanguage(true)), "app.components.custom.key") %>
after importing I18n
<%@ page import="com.day.cq.i18n.I18n" %>