Results tagged “Adobe CQ5”

Building an Accordion Component in Adobe CQ5

Over the past year, I have been developing websites with Adobe CQ5 as the CMS (Content Management System), including building components, so that content writers can populate the web pages. In some cases, the logical method of creating components did not work; with any CMS, there are limitations or bugs, and part of the 'fun' (if you could call it that) is discovering an alternative solution. This article describes and explains the accordion component development. This component was developed nearly one year ago now, so some of the particulars are not as fresh in my mind.

What The Heck is An Accordion in Web Terms?

For those who do not know, an 'accordion' in web terminology is a design element that can show or hide a panel of content (to save screen space or provide a consistent grouping of similar data), and the user can click onto the panel to expand the minimised view, or to minimise an expanded panel. The screenshot below shows an example of the component, which was the solution I implemented. Obviously, the styling (CSS) and Javascript required is beyond the scope of this. (For those who are interested, the functionality of the interaction is completed using the JQuery Javascript library.)

cq5accordion1.jpg

For setting this component up in CQ5 CMS for the content editors to use, I ideally wanted the content writer to be able to add a panel for each 'accordion' entry, which would consist of a title/subject and body text. The body text needed the ability to be styled, so the custom CQ5 rich text editor needed to be used. This would have been using a compositeField / MultiField component, but a bug was discovered while creating this, and the values did not save correctly. Unfortunately, Adobe CQ5 CMS cannot handle certain data types, even though it was meant to be supported. (Adobe CQ5 CMS does tend to have a lot of "TODO" comments in its code.)

Obviously, I needed to come up with an alternative and user-friendly solution. I read in forums online about using the column component and adapting it, but I wanted it to be more intuitive to the content writers. I'm mainly writing about my experience here as there seems to be many wanting to complete the same task, but the information does not exist.

My Accordion CQ5 Solution Explained

The alternative solution was to develop the accordion and accordion panel components separately, as a parsys, while providing a user-friendly interface to give the content writers direction. Simply, the content writer will drag and drop an accordion component from the Sidekick onto the screen. The accordion component will have a placeholder message to instruct the user to add accordion entries. The user will double-click the accordion component on the screen to add accordion entries. (The accordion entries are simply another component.) The accordion entries component is the only type of component that they will be able to add inside the accordion component parsys; no other components will be allowed to be placed.

This tutorial shows some of the steps to create an accordion component in Adobe CQ5 CMS. First of all, I will explain the structure of the set-up for the component. A visual representation of the structure is displayed below. As you can see, the accordion is organised into the 'accordion' and 'accordion-entry' (one panel, consisting of a heading and rich text) components.

cq5accordion2.jpg

The 'accordion' Component
The 'Accordion' component is simply the placeholder that encompasses the accordion entries.

_cq_editConfig.xml:
To ensure that the screen updates so that the editor can see the output on the screen, the page in author mode in the CMS needs to be refreshed. The file demonstrates refreshing after creation, after deletion, after insertion, and after moving.

<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    cq:dialogMode="floating"
    jcr:primaryType="cq:EditConfig">
    <cq:listeners
        jcr:primaryType="cq:EditListenersConfig"
        aftercreate="REFRESH_PAGE"
        afterdelete="REFRESH_PAGE"
        afterinsert="REFRESH_PAGE"
        aftermove="REFRESH_PAGE"/>
</jcr:root>

.content.xml
The 'Accordions' .content.xml file specifies that the sling:resourceSuperType is the standard parbase component. This will allow us to drag and drop other components into it. However, we need to ensure that only a specific type of component can be put into that place - the 'accordion-entry'. The settings allowedChildren is set to be an 'accordion-entry' component type, and allowedParents is the parsys.

<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    cq:isContainer="{Boolean}true"
    jcr:primaryType="cq:Component"
    jcr:title="Accordion"
    sling:resourceSuperType="foundation/components/parbase"
    allowedChildren="[*/accordion-entry]"
    allowedParents="[*/parsys]"
    componentGroup=".hidden"/>

dialog.xml
When the user drags and drops the 'Accordion' component into place, they have the option to enter a unique ID for the accordion. See the snippet of code below.

<items jcr:primaryType="cq:WidgetCollection">
        <title
            jcr:primaryType="cq:Widget"
            fieldDescription="Leave empty to use the page title."
            fieldLabel="Title"
            name="./jcr:title"
            xtype="textfield"/>
        <id
            jcr:primaryType="cq:Widget"
            fieldDescription="Enter a unique ID for the accordion"
            fieldLabel="ID"
            name="./id"
            xtype="textfield"/>
    </items>

accordion.jsp
The following shows the contents of the Accordion JSP and how it is rendered on the page. The resourceType is a parsys, since the content editor will be dragging and dropping the 'according-entries' components into place here.

<c:set var="accordionFlag" scope="request" value="yes"/>
<c:set var="accordionID" scope="request" value="1"/>
<div><cq:include path="entries" resourceType="myproject/components/my-accordion/components/parsys"/></div>

clientlibs folder
This folder holds the Javascript for the accordion. There's some configuirations here, such as defining the client libraries, such as the Javascript/jQuery file that will handle how the accordion should behave. The Javascript file is placed into the 'source' folder underneath the 'clientlibs' folder. Note that the name must match the name in the js.txt file.

  • .content.xml:
    <jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
        jcr:primaryType="cq:ClientLibraryFolder"
        categories="[my.accordion-component]"/>
  • js.txt:
    #base=source
    jaccordion.congif.js

The 'accordion-entry' Component
The 'Accordion-entry' component is an actual entry or panel that sits inside the 'Accordion' component. This is a child of the 'Accordion' component.

.content.xml:
The 'accordion-entry' will only be allowed to be used if it is a child of the 'Accordion' component, so we set the allowedParents accordingly.

<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:Component"
    jcr:title="Accordion Entry"
    sling:resourceSuperType="foundation/components/parbase"
    allowedParents="[*/my-accordion/components/*parsys]"
    componentGroup=".hidden"/>

dialog.xml:
The 'accordion-entry' dialog allows the user to enter a title for the accordion entry panel as well as rich text for the body text of the accordion.

<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:Dialog"
    helpPath="en/cq/current/wcm/default_components.html#Text"
    title="Text"
    xtype="tabpanel">
    <items jcr:primaryType="cq:WidgetCollection">
        <tab1
            jcr:primaryType="cq:Widget"
            anchor="100%"
            title="Text"
            xtype="panel">
            <items jcr:primaryType="cq:WidgetCollection">
                <title
                    jcr:primaryType="cq:Widget"
                    defaultValue="enter a title"
                    fieldLabel="Title"
                    name="./title"
                    xtype="textfield"/>
                <isRichTextFlag
                    jcr:primaryType="cq:Widget"
                    ignoreData="{Boolean}true"
                    name="./textIsRich"
                    value="true"
                    xtype="hidden"/>
                <text
                    jcr:primaryType="cq:Widget"
                    defaultValue="Please enter some text"
                    fieldDescription="Text displayed in panel"
                    fieldLabel="Text"
                    hideLabel="{Boolean}true"
                    name="./text"
                    xtype="richtext"/>
            </items>
        </tab1>
    </items>
</jcr:root>

accordion-entry.jsp:
The JSP renders the accordion-entry's HTML. I'm not going to include all of the file's contents, but note that I use the lines below in order to obtain the title and text, set by the content editor by using the contents of the dialog.xml file above.

<%
final String title = properties.get("title", "");
final String text = properties.get("text","");
%>


The 'parsys'
The parsys is used for ensuring that the component has the same properties to behave like the foundation parsys component. This component is a copy of the component in the foundation library, with a change to a few of the files for the accordion. The changed files are mentioned below.

.content.xml:
The parsys component superResourceType is the foundation's parsys component, and the allowedChildren is 'accordion-entry'.

<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    cq:isContainer="{Boolean}true"
    jcr:primaryType="cq:Component"
    jcr:title="Accordian Composite 1"
    sling:resourceSuperType="foundation/components/parsys"
    allowedChildren="*/*accordion-entry"
    componentGroup=".hidden"/>

.content.xml (in the 'new' folder)
The resourceType needs to point to the accordion's copy of the parsys file.

<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:Component"
    jcr:title="New Paragraph"
    sling:resourceType="myprojectx/components/my-accordion/parsys/new"
    componentGroup=".hidden"/>

_cq_editConfig.xml (in the 'new' folder) 
Simply, we will tell the user to drag and drop accordion entries to this place. (So, we change the emptyText parameter here.)

<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    cq:actions="[_clear,insert]"
    cq:emptyText="Drop Accordian entries here"
    jcr:primaryType="cq:EditConfig"/>

Conclusion

Hopefully, I hope I have not missed anything important out from these steps. (It was a while ago since this was developed, so it's not very fresh in my memory.) I hope that this will allow you to think of alternative solutions where some of the components in CQ5 do not work as expected or as documented. The most important point is to develop the CMS website customisation so that the user can intuitively add their content and be prevented from making changes that could 'break' the website.

One more tip: I also think it's important to note that you can switch off Javascript or JQuery from running in EditMode, and this was done so that the user can view and edit all panels in the accordion by clicking onto any panel (without the behaviours applied to expand and contract).

Happy programming! 

Latest Project: NADEX Website

I have been a very busy girl over the past three months. I have been the technical lead for the re-development of a website, including incorporating the new design into a new Content Management System (Adobe CQ5 CMS), which I have been developing in for nearly a year. In fact, another website that I spent the majority of the past year developing using the same CMS went live in January, so a lot has been happening this year.

This project certainly had some challenges, all of which were not surprising considering that the project was the first public-facing website (consisting of many additional dependencies) to use the new CMS, and the deadline was tight and had to be met in time. I have noted the following list of challenges:
  • The redevelopment of this website had to be achieved by 1 February. This meant that we only had approximately two months to spend for development tasks.
  • To meet the tight mid-week deadline, we had to break from some internal processes. Typically, releases are completed at weekends, and code was being redeveloped until two weeks before the go-live date, and bugs were being fixed up until the go-live date.
  • Many environment and infrastructure issues needed to be addressed, and new environments needed to be built. This was the first time that the new CMS was used for a public-facing website.
  • Other web-based applications use files that exist under the domain, and it was not always clear where the files were being used. These files, HTML pages, and links needed to be migrated and approprite RewriteRules needed to be written so that the changes would not affect these other web-based systems.
  • A new brand and designs for the website were being created at the same time, and the branding was received half-way through the design process. (Due to the tight deadline, designs had to be started before a new brand was created.) Additionally, the development process started at the same time as the designs were being created during the first two sprints. This, of course, meant that we needed to constantly make small changes to the CSS and HTML for design changes.
  • The development for the project was achieved in approximately two months, including bug-fixing during the final two weeks, and some earlier development work needed to be tweaked as unfinished designs were evolved. (We certainly did work Agile.)

nadex_home.jpg

Despite the mentioned challenges, everyone did a fantastic effort, and I largely enjoyed it. Many disciplines (such as development, design, QA, content writers, system developers, etc) worked well together to ensure the success of the project. 

With such a project, the low points were working long hours over the Christmas and New Year weeks while colleagues and most of the company were on holiday, working through most of my lunches throughout the past three months, and ensuring that the dependent systems were seemingly unaffected by the changes. The highs were speaking to the clients and being involved at a high level, developing new components in the CMS using Java, and working together toward a common goal to launch a complete website. Now that this project is finished, I think some sort of recovery is in order.
1

Tags

Archives

Recent Comments

  • jenn: Thank you. read more
  • Murge: Amazing post. read more
  • Herbert: good post. site read more
  • Frank Quake: Hey, This is great when you said that I had read more
  • Chappy: You mention peptides here? I have had first hand experience read more
  • jenn: Thanks! I love the work. I have got more recent read more
  • Fanakapan: Thanks for the write up. This was some of my read more
  • jenn: Yes.... but that's only for the islands. Mostar and Montenegro read more
  • jenn: Hello, the code is not mine to hand out. I'll read more
  • pantich: More info about the best day trips from Dubrovnik can read more
OpenID accepted here Learn more about OpenID