Thursday, August 25, 2011

What Does "cannot read item cafebabe-cafe-babe-cafe-babecafebabe" Error mean While uploading package

Above Error mean that You are not logged in as Admin user before uploading the package.

Regarding package share you could also get error "Item cannot be saved because it has been modified externally"

If you are getting this error in CQ5.3/CRX2.0 -- Solution would be to go to CRX explorer and then click on revert all on the top. Or navigate to uploaded package under /etc/packages and then remove that package.
Good solution would be to upgrade to CRX2.1/CRX2.2

If you are getting this error in CRX2.1 -- As a workaround you can touch this package again by going to package share -> Then select that package and then click on rewrap. Also you can try to use CQ package manager instead if nothing works.

Reason why you get this error because CQ package manager interfere with CRX package manager (Disabling any one of them will resolve this issue permanently ) when you install a package. I have not this issue in CRX2.2.

Sunday, August 21, 2011

How to Remove .html extension from URL in CQ Or How to Implement New Rewriter Pipeline in CQ / AEM

Note: CQ Need extension to understand and serve incoming request. There is no way you can have publish site extension less (Unless it is vanity URL). You can however make your public site extension less by tweaking apache and CQ config.

For CQ < 5.5

You could use Sling Rewriter to remove html from the URL.
Use this package (With some pom.xml changes)

You need following configuration changes,

create a node in the repository at /apps/myapp/config/rewriter/html-remover (the names 'myapp' and 'html-remover' can be whatever you want). This node must have the following properties:

* enabled (Boolean) - set to true
* serializerType (String) - set to htmlwriter
* generatorType (String) - set to htmlparser
* order (Long) - set to a number greater than 0
* contentTypes (String[]) - set to text/html
* transformerTypes (String[]) - set to linkchecker, html-remover

It might also be simpler to copy the node /libs/cq/config/rewriter/default to /apps/myapp/config/rewriter/html-remover and then add html-remover to the multi-valued transformerTypes property.

Some additional Questions and answer

Question: What are transformerTypes? I just set it to img-src-cdn-prefixer only without linkrewriter, mobile.....etc And it seems to work. Does transformerTypes define entire pipeline? If I specify it to be {"linkchecker", "img-src-cdn-prefixer, mobile, mobiledebug"} will the pipeline be: htmlparser -> linkchecker -> img-src-cdn-prefixer -> mobile -> mobiledebug -> htmlwriter ?

Answer: That is correct

Question What are htmlwriter (serializer) and htmlparser (generator) ? I assume these are default generator and serializer for default pipeline for .html ?

Answer: serializer marks the end of pipeline. so for /libs/cq/config/rewriter/default it would be htmlwriter->linkchecker->htmlwriter

and for /libs/cq/config/rewriter/pdf it would be html-generator->htmlparser->xslt->fop

Question: Do you recommend defining my own pipeline component? (by setting pipeline.type = "img-src-cdn-prefixer").
Or, should I use pipeline.mode = "global" ? If I used pipeline.mode = "global", would I be able to disable my component? Maybe by setting service.ranking to negative?

Answer: first option is to define pipe line as component and second option is once you have a component and you want to extend it. You can put new component in your pipeline based on ranking.

it is mentioned in

Question: If I wanted to beautify html output, would I implement TransformerFactory and use tidy html or similar, and put it right before serializer?

Answer: In theory yes.

Note: This feature would be present OOTB in next release of CQ. You can also ask for paid feature pack for this for CQ5.4 version.

For CQ > 5.5

Note that your application does not work with extension less URL, CQ needs selectors in order to find appropriate resource. Above setting just remove .html extension from Links but eventually in order to serve those pages you need internal ".html" extension. You can use rewrite rule like this to achieve this

Apache Changes 

Above configuration will remove html extension from embedded link. But your goal is to have incoming URL as extension less. You need to consider following,

1) Some one coming with .html extension ----> remove extension
2) Some one coming without extension -----> map to something CQ understand. Mean add .html
3) Some one coming with selectors as extension ----> Just remove what you want to remove
4) Some one coming with a URL for which removing extension is not desirable ----> Exclude them from extension removal

# Set Up Env Variable for extension Less URL
# This mean that if URL does not start with /etc/design or /bin/wemblog (This is where you will have #your custom servlet)
#Also if URL does not have any extension then this url qualifies for extension less
RewriteCond %{REQUEST_URI} !^/bin/wemblog(.*) [NC]
RewriteCond %{REQUEST_URI} !^/etc/designs(.*) [NC]
RewriteCond %{REQUEST_URI} !(.*)\.[a-zA-Z0-9-]+$
RewriteRule .* - [E=EXTENSION_LESS_URL:1]

#If it is selector then don't remove html extension
#Here we are checking for more than 2 dots occurance
RewriteCond %{REQUEST_URI} .*(\.[a-zA-Z0-9-]*){2,}

# To make thing configurable add few thing which will not be considered for extension less
RewriteCond %{REQUEST_URI} !^/<some path you don't want to remove extension>(.*) [NC]
RewriteCond %{REQUEST_URI} !^/etc/designs(.*) [NC]

# If some one come with / in end then remove it
RewriteCond %{REQUEST_URI} !^/$ [NC]
RewriteRule ^(.*)/$ $1 [R=301,L]

# Now remove extension if some one comes with extension

# If some one comes with .html as extension then redirect them to non html URL
RewriteRule ^(.*)\.html$ https://%{HTTP_HOST}$1 [R=301,L]

# If some one comes with .html as extension then redirect them to non html URL
RewriteRule ^(.*)\.htm$ https://%{HTTP_HOST}$1 [R=301,L]

# Now time to handle extension less to be passed with extension so that publish understand request

#If URL has multiple extensions, and can have /content and it ends with html
RewriteCond %{REQUEST_URI} !^/etc/designs(.*) [NC]
RewriteCond %{REQUEST_URI} !^<some more path you want to exclude>(.*) [NC]
RewriteCond %{REQUEST_URI} .*(\.html)
RewriteRule ^(/.*)$ $1  [L,PT]

#If request do not have html extension then add html extension to it
#This assume that you already removed /content from URL
RewriteCond %{REQUEST_URI} !^/content/dam(.*) [NC]
RewriteCond %{REQUEST_URI} !^/content(.*) [NC]
RewriteCond  %{ENV:EXTENSION_LESS_URL} !^$
RewriteRule ^(/.*)$ $1.html [L,PT]

# If something is missed in the end
RewriteCond  %{ENV:EXTENSION_LESS_URL} !^$
RewriteRule ^(/.*)$ $1.html  [L,PT]

Custom generator example for XML:

Welcome to Adobe Communique Blog


My name is Yogesh Upadhyay and I am working on CQ (Now called WEM/AEM) product as Application Architect in Citrix Systems Prior to that worked as CS engineer in Adobe Systems for few years. I started my Career as System Analyst on CQ4 projects. Feel free to post your questions and I will do my best to answer them. Will try to update this blog as much I can. I would like to give personal Thanks for all my team member and employee for helping me to gain this knowledge. Hopefully this Blog will spread more awareness about the product and will make our Job easy.