About Me

I write therefore I am a writer.

These words are mine, and although they might lack in grammar or grace, if you look beyond these words you will feel the concepts I have tried to express. 

Much of the content here is technical, relating to my history as a developer. My future is in technical architecture, content strategy, enterprise content and giving guidance in these areas.

I try to publish something new every two weeks alternating between topics.

Navigation
Social

Entries in cms (4)

Sunday
Jan152012

CQ5 best practices for component development

Following on from my advice for best practices for developing with Adobe Day CQ5, here are some suggestions centred around component development - you should tailor these to fit your needs. They should help if you are unsure where to start. There's lots of technical documentation on the product itself and the core open source frameworks; elements of these are useful for developers, but there's scant information on methodologies or strategies you can apply when starting out. Some of this may also apply to other systems albeit with different no-go areas and so on.

Avoid copying components

Firstly, avoid modifying anything under /libs. Also avoid copying anything from /libs to /apps. There are a few reasons for this:

  1. If you upgrade you will hate yourself for doing this. Your boss and co-workers may hate you too.
  2. Changing /libs implies that you are either not going to version control it, or that you are going to. Either way leads to madness, unless you like code to go missing and have servers which behave differently or if you want to add half of the core product to subversion. 

Copies to /apps should be VERY limited for a few significant reasons:

  1. when you upgrade, you need to upgrade this code too if you want it to work or at the very minimum have the new features. 
  2. there's no way of quickly identifying these 'overlays'.
  3. if you overlay something that is key, things go sour very quickly post-upgrade.
  4. having two components with the same name in the same group breaks design mode in CQ5.4 - for me at least

Override the bare minimum

All components for paragraph systems should have a 'sling:superResourceType ' of 'foundation/components/parbase'. Development of derived components should be done using 'sling:superResourceType' where possible. An example might be creating a paragraph system that behaves differently. Say you want to make one where component display is inverted, so that new components are inserted at the top - this is a parsys with a 'sling:superResourceType' of 'foundation/components/parsys' and a customised script. There's no need to copy the whole component.

Component Organisation

A recommended structure for component definition is

 /apps/<site-id>/components/page/<component>
/apps/<site-id>/components/content/<component>
/apps/<site-id>/src
/apps/<site-id>/install 
/apps/<site-id>/widgets
/apps/<site-id>/nodetypes
/apps/<site-id>/templates/<template>

Of course, all of these are optional. Page rendering components explicitly defined in the templates are split from paragraph and non-whole-page components such as navigational bars. This is purely for the benefit of developers; it means it's possible to see at a glance if the component is used to render a whole page or if it might appear as part of a page - a useful distinction. It has another benefit, for example it allows a 'sitemap' paragraph component which lists in HTML format to exist as well as a machine-readable sitemap.xml page type for SEO - two very different things with the same name.

Composition of Page Types 

A process of decomposition into sub-scripts is applied to the page rendering code to create a solid foundation which will allow extension of the basic type into more specifc page components:

/apps/<site-id>/components/page/base
/apps/<site-id>/components/page/base/base.jsp
/apps/<site-id>/components/page/base/head.jsp
/apps/<site-id>/components/page/base/body.jsp
/apps/<site-id>/components/page/base/header.jsp
/apps/<site-id>/components/page/base/content.jsp
/apps/<site-id>/components/page/base/footer.jsp

The base component extends the foundation page, with a 'sling:superResourceType ' of 'foundation/components/page'. 'base.jsp' basically sets the page doctype, outputs the <html> tags and includes head and body. Subsequenty, body.jsp includes header.jsp, content.jsp, and footer.jsp.

Extensible Page Components

This is the minimum for a base component which is extensible. We can easily make this better by adding other override-able scripts, such as adding an analytics.jsp or a meta.jsp. From this start point we can create a new component with a 'sling:superResourceType ' of '<site-id>/components/page/base', and the only thing we need to create is content.jsp

/apps/<site-id>/components/page/twocolumn/content.jsp
/apps/<site-id>/components/page/twocolumn/left.jsp
/apps/<site-id>/components/page/twocolumn/right.jsp

This obviously a two column layout. In order to separate content from code we should create a new component with a 'sling:superResourceType ' of '<site-id>/components/page/twocolumn', which now needs no scripts at all. It will derive all configuration and code from the super type, leaving us free to change the super type if we want a different representation (so long as the paragraph systems have the same names). We can also override the two column layout if we so chose, by creating a script which does something then including the overridden script. For example, we could create a  /apps/<site-id>/components/page/contentpage/right.jsp script which displays a title component then includes the  /apps/<site-id>/components/page/twocolumn/right.jsp  script. This gives a great level of flexibility.

Content has a type

Remember that when content is being created, the component path is 'stamped' into the content so that Sling knows what script to use to render it. Always plan components so that an appropriate resource type is associated with the content. In our page example, it is much better that it is a 'content page' than a 'two column page' or even a 'base page' as the intent is that is it content. The fact that it displays in two columns is incidental, especially if in six months time a third column is added. It's much more future proof to use a layer of inheritance, but only if it doesn't add unnecessary complexity.

Favour composition over inheritance

Components is CQ5 should also favour composition over inheritance. If you want a list-image component for example, don't take a list component, copy it, and hack it to have an image. A reasonable approach is to create a new component and add the necessary components to it. When you upgrade CQ to a new version, you'll have no changes to make - it'll automatically use the new version. If you did it by creating a new component by forking code, you could find it difficult to get it working if there have been major changes to the original component.

I hope this guide has been useful. It's based on real world development practices and is the basis of any recommendation I would give at this time. 
Sunday
Nov062011

Magnolia CMS

I’m developing a website using Magnolia CMS and I’m mighty impressed so far. Firstly, it’s been very easy to get it up and running in the tiny memory constraints that I have imposed upon it; it needs to work on a 512mb virtual machine because I don’t want to pay more for my hosting, and it's a good challenge to try and get a stock product with modern feature to work reliably in a confined space. Secondly it needs full user access rights, and it’s been very simple to configure and test. Finally the stock templates are actually useful and I’ve needed to do the bare minimum of customisation so far.

It's for a personal site, so I’m sure there would be other challenges if I had specific functionality that was needed and a design constraints but as it uses a template system it looks like this is part of it’s internal design to allow massive customisation of the output. It seems to run quickly even though it has virtually no heap space to use, and is stable. Some of the included features are fantastic, such as the ability to do polling import of RSS feeds which will allow me to pull in this blog for example. It also can aggregate the RSS to merge and filter which is very powerful.

The Digital Asset Management features are good too, I can upload an image, tag it, and attribute it with the Creative Commons information for the source so that I can add the links back to the creator. There are neat image gallery tools too which list whole folders of images and display thumbnails with big versions shown using a ‘lightbox’ style when they are clicked on.

My only gripe so far is that when a page is given an image it’s used in different ways; by the page itself, in search results, in teasers, and in carousels. Unfortunately it sometimes scales the image without regard to the aspect ratio thus squashing it. There is an add-on available to do image manipulation but it’s only for the Enterprise Edition and they don’t publish the price of that licence. It’s the only EE feature that I would like so it’s highly unlikely to be worth it. Thankfully it does have the option to override the image in these components which means I have to manually create a new image using a desktop application but that’s not too tricky. It would have been nice to have some basic crop and scale image tools built in, especially as Magnolia is a Java application so there are lots of free open source libraries which can provide some very advanced functionality. 

A link to the new site will follow when it’s launched… soon.

Monday
Oct312011

NuxeoWorld

Last week I went to Paris to find out more about Nuxeo, an enterprise content management system. It seemed like a very polished product developed by a highly professional company and I was impressed by its capabilities. It’s very much geared towards Case Management and Document Management as it centres itself on workflow and processing of content items in a structured manner, with item state as a core tenet of the system.

I liked the idea of the Nuxeo Studio, a web based facility that allows changes to be made then deployed to live servers but also facilitates support of the live systems and distribution of the development effort. It also enables automatic upgrading which is a nice idea. They are also embracing the cloud with their Nuxeo Platform platform-as-a-service offering which is an intriguing proposition.

It’s a very different platform offering to the WCM systems I have implemented before, and I think this is a great niche to watch to see how it evolves. It’s a complementing system which is more about items which have lifespans and transitions between states as opposed to the web content created by CMS implementations I have done using Adobe Day CQ5, Umbraco, or Magnolia CMS.

I met some interesting people there, and I had a great evening out. I look forward to meeting you all again soon, and to the next Nuxeo event.

[photos to follow]

Monday
Oct102011

Dynamic data lists in CQ5

The author-mode edit dialogues in CQ5 are great especially if you populate them with your own options for dropdown lists. If you have a nice handy JSON data source which is conveniently organised into key/value pairs, you can use this in your CQ5 author dialogues to provide the values for dropdowns, combo boxes, and lists of radio buttons and checkboxes. It's very easy if you data that looks something like this:

{"mydata":[
{"id":"1","label":"one"},
{"id":"2","label":"two"},
{"id":"3","label":"three"},
{"id":"4","label":"four"},
{"id":"5","label":"five"},
{"id":"6","label":"six"}
]}

when you create the edit control in the dialog, set these properties and it will load the remote data and use it

optionsProvider = URL
optionsRoot = 'mydata'
optionsLabelField = 'label'
optionsValueField = 'id'
xtype = 'selection'
type = 'select' [or radio, checkbox, combo]

along with all the usual properties, and it should show your data labels in the drop down, and store the values in the repository. There are some caveats as noted in the documentation, mostly that the data needs to be HTML entity encoded or escaped otherwise < and > do bad things. It's also not clear how to unselect it and have no option in the saved data, so you might need to design the dialog with this in mind. Finally, the defaults for the checkboxes are somewhat questionable.