CQ5 best practices for component development
Sunday 15 January 2012 at 12:00 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:
- If you upgrade you will hate yourself for doing this. Your boss and co-workers may hate you too.
- 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:
- 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.
- there's no way of quickly identifying these 'overlays'.
- if you overlay something that is key, things go sour very quickly post-upgrade.
- 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
Favour composition over inheritance
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.
Antony |
4 Comments |
ECM,
WCM,
WCMS,
adobe,
best practices,
cms,
communique,
cq5,
day in
CQ5,
Content Management,
Development,
Guides,
Web Development 