110
CQ5 WCM Developer's Guide

Cq5 Guide Developer

Embed Size (px)

Citation preview

Page 1: Cq5 Guide Developer

CQ5 WCM Developer's Guide

Page 2: Cq5 Guide Developer

CQ 5.2 WCMCopyright 1993-2009 Day Management AG

CQ5 WCM Developer's Guide

Page 3: Cq5 Guide Developer

Page iii of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Contents1. Introduction ........................................................................................................................ 1

1.1. Introduction ............................................................................................................. 11.2. Purpose of this Document ........................................................................................ 11.3. Target Audience ...................................................................................................... 11.4. Prerequisites for development within CQ .................................................................. 1

2. CQ in-depth ....................................................................................................................... 22.1. JSR-170 and the JCR API ....................................................................................... 22.2. CQ DAM ................................................................................................................. 22.3. Widgets .................................................................................................................. 22.4. FileVault (source revision system) ............................................................................ 22.5. Workflow Engine ..................................................................................................... 22.6. Dispatcher ............................................................................................................... 22.7. Localization ............................................................................................................. 22.8. Sling Request Processing ........................................................................................ 3

2.8.1. Introduction to Sling ...................................................................................... 32.8.2. Sling is Content Centric ................................................................................ 32.8.3. RESTful Sling ............................................................................................... 32.8.4. URL Decomposition ...................................................................................... 32.8.5. From URL to Content and Scripts .................................................................. 42.8.6. Sling API ...................................................................................................... 82.8.7. Referencing existing elements using sling:include ........................................... 82.8.8. First Steps - an example for using Sling ......................................................... 8

2.9. OSGI ...................................................................................................................... 83. CQ5 WCM - Architecture and Concepts ............................................................................ 10

3.1. Development objects ............................................................................................. 103.2. Structure within the repository ................................................................................ 11

4. Development Tools ........................................................................................................... 124.1. Working with the CQ Development Environment (CQDE) ......................................... 12

4.1.1. Setting up CQDE ........................................................................................ 124.1.2. Configuring CQDE ...................................................................................... 12

4.2. How to Set Up the Development Environment with Eclipse ....................................... 124.2.1. Creating the Project Structure in CQ5 .......................................................... 134.2.2. Installing FileVault (VLT) ............................................................................. 134.2.3. Installing Eclipse ......................................................................................... 144.2.4. Creating the Project Structure in Eclipse ...................................................... 144.2.5. Scripting with Eclipse and CQ5 .................................................................... 194.2.6. Java Developing with Eclipse and CQ5 ........................................................ 204.2.7. Building collaborative and automated projects ............................................... 22

5. Designer .......................................................................................................................... 246. Templates ........................................................................................................................ 25

6.1. What are Templates? ............................................................................................ 256.2. Overview of templates ........................................................................................... 256.3. How Templates are structured ................................................................................ 25

6.3.1. The structure of a Template ........................................................................ 256.3.2. The content produced by a Template ........................................................... 27

6.4. Developing Page Templates ................................................................................... 286.4.1. Creating a new Template (based on an existing template) ............................. 28

6.5. Summary .............................................................................................................. 297. Components ..................................................................................................................... 30

7.1. What exactly is a Component? ............................................................................... 307.2. Default Components within CQ WCM ..................................................................... 307.3. Components and their structure .............................................................................. 31

7.3.1. Component definitions ................................................................................. 317.3.2. Component definitions and the content they create ....................................... 337.3.3. Component Hierarchy and Inheritance .......................................................... 35

Page 4: Cq5 Guide Developer

CQ5 WCM Developer's Guide

Page iv of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

7.3.4. Summary .................................................................................................... 357.4. Developing Components ........................................................................................ 36

7.4.1. Developing a new component by adapting an existing component .................. 367.4.2. Adding a new component to the paragraph system (design mode) .................. 377.4.3. Extending the Text and Image Component - An Example .............................. 38

7.5. Further Development of Specific Components and Tools .......................................... 447.5.1. Developing the Bulk Editor .......................................................................... 44

7.6. Scripts .................................................................................................................. 527.6.1. global.jsp .................................................................................................... 527.6.2. JSP Tag Libraries ....................................................................................... 53

7.7. A closer look at a few of the foundation components... ............................................. 607.7.1. Top Navigation Component ......................................................................... 607.7.2. List Children Component ............................................................................. 627.7.3. Logo Component ........................................................................................ 637.7.4. Paragraph System ...................................................................................... 647.7.5. Image Component ...................................................................................... 647.7.6. Text & Image Component ........................................................................... 667.7.7. Search Component ..................................................................................... 67

8. Guidelines for Using Templates and Components .............................................................. 689. Java WCM API ................................................................................................................ 6910. Multi Site Manager for Developers ................................................................................... 70

10.1. MSM in the Repository ........................................................................................ 7010.1.1. MSM-specific Nodes, Node Types, and Properties ...................................... 7010.1.2. MSM mechanisms in the repository ............................................................ 73

10.2. Extending MSM Functionalities ............................................................................. 7410.2.1. How to extend synchronization actions ....................................................... 7410.2.2. How to define the properties and the nodes that are copied to the LiveCopy .................................................................................................................... 8310.2.3. How to remove the "Chapters" step in the "Create Site" wizard ..................... 84

11. How to Create a Fully Featured Internet Website ............................................................. 8512. DAM Media Handlers ..................................................................................................... 86

12.1. Default Media Handlers ........................................................................................ 8612.2. Using Media Handlers in Workflows to perform tasks on Assets .............................. 8712.3. Disabling/Enabling a Media Handler ...................................................................... 9012.4. Creating a new Media Handler ............................................................................. 91

12.4.1. Important Classes and Interfaces ............................................................... 9112.4.2. Example: create a specific Text Handler ..................................................... 91

13. Data Modelling ............................................................................................................... 9813.1. Data Modeling - David Nuescheler's Model ........................................................... 98

13.1.1. Source ...................................................................................................... 9813.1.2. Introduction from David ............................................................................. 9813.1.3. Seven Simple Rules .................................................................................. 98

A. Keyboard Shortcuts ........................................................................................................ 104B. Security Checklist ........................................................................................................... 105

B.1. Use the user session, not the administrative session ............................................. 105B.2. Check for Cross-Site Scripting (XSS) .................................................................... 105

C. Copyright, Licenses and Formatting Conventions ............................................................. 106C.1. Formatting Conventions ....................................................................................... 106

Page 5: Cq5 Guide Developer

Page 1 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

1 Introduction1.1 Introduction

Day's CQ5 platform allows you to build compelling content-centric applications that combineWeb Content Management, Workflow Management, Digital Asset Management and SocialCollaboration.

The product has been completely redesigned from Communiqué 4, allowing Day to use newarchitecture and technologies, thus increasing functionality while reducing complexity. Extensiveuse of standards helps ensure long-term stability.

1.2 Purpose of this Document

To provide the information necessary for developing new components, applications and otherelements within CQ.

Warning

This document is not a programming guide; it is assumed that you have the necessaryskills for writing code in the appropriate language.

Important

This document is designed to be read in conjunction with the CQ5 WCM Architect Guide.

1.3 Target Audience

• Developers

1.4 Prerequisites for development within CQ

For development within CQ, you need the following skills:

• Basic knowledge of web application techniques, including:

• the request -response (XMLHttpRequest / XMLHttpResponse) cycle

• HTML

• CSS

• JavaScript

• Working knowledge of CRX; including the Content Explorer

• Basic knowledge of JSP (JavaServer Pages), with the ability to understand and modify simpleJSP examples

Page 6: Cq5 Guide Developer

Page 2 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

2 CQ in-depth2.1 JSR-170 and the JCR API

JSR 170 is the Java Specification Request for the Content Repository for JavaTM technology API.Specification lead is held by Day Software AG.

The JCR API package, javax.jcr.* is used for the direct access and manipulation of repositorycontent.

CRX is Day's proprietary implementation of the JCR.

Apache Jackrabbit is an open source, fully conforming, implementation of this API.

2.2 CQ DAM

CQ DAM (Communiqué Digital Asset Management) is used to centrally manage all digital mediafiles and essential metadata information.

2.3 Widgets

CQ WCM has been developed using the ExtJS library of widgets.

2.4 FileVault (source revision system)

FileVault provides your JCR repository with file system mapping and version control. It can beused to manage CQ development projects with full support for storing and versioning project code,content, configurations and so on, in standard version control systems (for example, Subversion).

2.5 Workflow Engine

Your content is often subject to organizational processes, including steps such as approval andsign-off by various participants. These processes can be represented as workflows, defined withinCQ, then applied to the appropriate content pages or digital assets as required.

The Workflow Engine is used to manage the implementation of your workflows, and theirsubsequent application to your content. More information on how to use Workflows is given in theChapter 8, .

2.6 Dispatcher

The Dispatcher is Day's tool for both caching and/or load balancing. Further information can befound under Tools - the Dispatcher.

2.7 Localization

Localization is at the core of CQ5. It provides support for adapting applications, created using theCQ5 platform, into different languages and regional configurations . While processing the request,the Locale is extracted. This is then used to reference a language code, and optionally a countrycode, which can be used for controlling either the specific content or format of certain output.

Localization will be used throughout CQ5 - wherever reasonable. One notable exception is thesystem log information of CQ5 itself, this is never localized and always in English.

Page 7: Cq5 Guide Developer

CQ in-depth

Page 3 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

2.8 Sling Request Processing

2.8.1 Introduction to Sling

CQ5 is built using Sling, a Web application framework based on REST principles that provideseasy development of content-oriented applications. Sling uses a JCR repository, such as ApacheJackrabbit, or Day's CRX, as its data store.

Sling started as an internal project of Day Management AG and is included in the installation ofCQ5. Sling has since been contributed to the Apache Software Foundation - further information canbe found at Apache.

Using Sling, the type of content to be rendered is not the first processing consideration. Instead themain consideration is whether the URL resolves to a content object for which a script can then befound to perform the rendering. This provides excellent support for web content authors to buildpages which are easily customized to their requirements.

The advantages of this flexibility are apparent in applications with a wide range of different contentelements, or when you need pages that can be easily customized. In particular, when implementinga Web Content Management system such as CQ WCM.

2.8.2 Sling is Content Centric

Sling is content-centric. This means that processing is focused on the content as each (HTTP)request is mapped onto content in the form of a JCR resource (a repository node):

• the first target is the resource (JCR node) holding the content

• secondly, the representation, or script, is located from the resource properties in combinationwith certain parts of the request (e.g. selectors and/or the extension)

2.8.3 RESTful Sling

Due to the content-centric philosophy, Sling implements a REST-oriented server and thus featuresa new concept in web application frameworks. The advantages are:

• very RESTful; resources and representations are correctly modelled inside the server

• removes one or more data models

• previously the following were needed: URL structure, business objects, DB schema;

• this is now reduced to: URL = resource = JCR structure

2.8.4 URL Decomposition

In Sling, and therefore also CQ5, processing is driven by the URL of the user request. This definesthe content to be displayed by the appropriate scripts. To do this, information is extracted from theURL.

If we analyze the following URL:

http://myhost/tools/spy.printable.a4.html/a/b?x=12

We can break it down into its composite parts:

Table 2.1. URL Decomposition

protocol host content path selector(s) extension suffix param(s)

http:// myhost tools/spy .printable.a4. html / a/b ? x=12

Page 8: Cq5 Guide Developer

CQ in-depth

Page 4 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

protocolHTTP.

hostName of the website.

content pathPath specifying the content to be rendered. Is used in combination with the extension; in thisexample they translate to tools/spy.html.

selector(s)Used for alternative methods of rendering the content; in this example a printer-friendly versionin A4 format.

extensionContent format; also specifies the script to be used for rendering.

suffixCan be used to specify additional information.

param(s)Any parameters required for dynamic content.

2.8.5 From URL to Content and Scripts

Using these principles:

• the mapping uses the content path extracted from the request to locate the resource

• when the appropriate resource is located, the sling resource type is extracted, and used to locatethe script to be used for rendering the content

The figure below illustrates the mechanism used, which will be discussed in more detail in thefollowing sections.

Figure 2.1. How Sling locates the content and scripts

Therefore:

Page 9: Cq5 Guide Developer

CQ in-depth

Page 5 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

• DO NOT specify which data entities to access in your scripts (as an SQL statement in a PHPscript would do)

• DO specify which script renders a certain entity (by setting the sling:resourceType propertyin the JCR node)

2.8.5.1 Mapping requests to resources

The request is broken down and the necessary information extracted. The repository is searchedfor the requested resource (content node):

• first Sling checks whether a node exists at the location specified in the request; e.g. ../content/corporate/jobs/developer.html

• if no node is found, the extension is dropped and the search repeated; e.g. ../content/corporate/jobs/developer

• if no node is found then Sling will return the http code 404 (Not Found).

Note

Sling also allows things other than JCR nodes to be resources, but this is an advancedfeature.

2.8.5.2 Locating the script

When the appropriate resource (content node) is located, the sling resource type is extracted. Thisis a path, which locates the script to be used for rendering the content.

The path specified by the sling:resourceType can be either:

• absolute

• relative, to a configuration parameter

Note

Relative paths are recommended by Day as they increase portability.

All Sling scripts are stored in subfolders of either /apps or /libs, which will be searched in thisorder.

A few other points to note are:

• when the Method (GET, POST) is required, it will be specified in uppercase as according to theHTTP specification e.g. jobs.POST.esp (see below)

• various script engines are supported:

• .esp, .ecma: ECMAScript (JavaScript) Pages (server-side execution)

• .jsp: Java Server Pages (server-side execution)

• .java: Java Servlet Compiler (server-side execution)

• .jst: JavaScript templates (client-side execution)

• .js: ECMAScript / JavaScript (client-side execution)

The list of script engines supported by the given instance of CQ are listed on the FelixManagement Console (http://localhost:4502/system/console/scriptengines ).

Page 10: Cq5 Guide Developer

CQ in-depth

Page 6 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Additionally, Apache Sling supports integration with other popular scripting engines (e.g., Groovy,JRuby, Freemarker), and provides a way of integrating new scripting engines.

Using the above example, if the sling:resourceType is hr/jobs then for:

• GET/HEAD requests, and URLs ending in .html (default request types, default format)

The script will be /apps/hr/jobs/jobs.esp; the last section of the sling:resourceTypeforms the file name.

• POST requests (all request types excluding GET/HEAD, the method name must be uppercase)

POST will be used in the script name.

The script will be /apps/hr/jobs/POST.esp.

• URLs in other formats, not ending with .html

For example ../content/corporate/jobs/developer.pdf

The script will be /apps/hr/jobs/jobs.pdf.esp; the suffix is added to the script name.

• URLs with selectors

Selectors can be used to display the same content in an alternative format. For example a printerfriendly version, an rss feed or a summary.

If we look at a printer friendly version where the selector could be print; as in ../content/corporate/jobs/developer.print.html

The script will be /apps/hr/jobs/jobs.print.esp; the selector is added to the script name.

• If no sling:resourceType has been defined then:

• the content path will be used to search for an appropriate script (if the path basedResourceTypeProvider is active).

For example, the script for ../content/corporate/jobs/developer.html wouldgenerate a search in /apps/content/corporate/jobs/.

• the primary node type will be used.

• If no script is found at all then the default script will be used.

The default rendition is currently supported as plain text (.txt), HTML (.html) and JSON (.json), allof which will list the node's properties (suitably formatted). The default rendition for the extension.res, or requests without a request extension, is to spool the resource (where possible).

• For http error handling (codes 404 or 500) Sling will look for a script at /libs/sling/servlet/errorhandler/404.esp, or 500.esp, respectively.

If multiple scripts apply for a given request, the script with the best match is selected. The morespecific a match is, the better it is; in other words, the more selector matches the better, regardlessof any request extension or method name match.

For example, consider a request to access the resource /content/corporate/jobs/developer.print.a4.html of type sling:resourceType="hr/jobs". Assuming we havethe following list of scripts in the correct location:

1. jobs.esp

2. jobs.GET.esp

Page 11: Cq5 Guide Developer

CQ in-depth

Page 7 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

3. jobs.GET.html.esp

4. jobs.html.esp

5. jobs.print.esp

6. jobs.print.a4.esp

7. jobs.print.html.esp

8. jobs.print.GET.html.esp

9. jobs.print.a4.html.esp

10.jobs.print.a4.GET.html.esp

Then the order of preference would be (10) - (9) - (6) - (8) - (7) - (5) - (3) - (4) - (2) - (1).

Note

(6) is a better match than (8), because it matches more selectors even though (8) has amethod name and extension match where (6) does not.

In addition to the resource types (primarily defined by the sling:resourceType property) thereis also the resource super type. This is generally indicated by the sling:resourceSuperTypeproperty. These super types are also considered when trying to find a script. The advantage ofresource super types is that they may form a hierarchy of resources where the default resourcetype sling/servlet/default (used by the default servlets) is effectively the root.

The resource super type of a resource may be defined in two ways:

1. by the sling:resourceSuperType property of the resource.

2. by the sling:resourceSuperType property of the node to which the sling:resourceTypepoints.

For example:

• /

• a

• b

• sling:resourceSuperType = a

• c

• sling:resourceSuperType = b

• x

• sling:resourceType = c

• y

• sling:resourceType = c

• sling:resourceSuperType = a

The type hierarchy of /x is [ c, b, a, <default> ] while for /y the hierarchy is [ c, a,<default> ] because /y has the slingresourceSuperType property whereas /x doesnot and therefore its supertype is taken from its resource type.

Page 12: Cq5 Guide Developer

CQ in-depth

Page 8 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

2.8.5.2.1 Sling Scripts cannot be called directly

Within Sling, scripts cannot be called directly as this would break the strict concept of a RESTserver; you would mix resources and representations.

If you call the representation (the script) directly you hide the resource inside your script, so theframework (Sling) no longer knows about it. Thus you lose certain features:

• automatic handling of http methods other than GET, including:

• POST, PUT, DELETE which are handled with a sling default implementation

• the POST.js script in your sling:resourceType location

• your code architecture is no longer as clean nor as clearly structured as it should be; of primeimportance for large-scale development

2.8.6 Sling API

This uses the Sling API package, org.apache.sling.*, and tag libraries.

2.8.7 Referencing existing elements using sling:include

A final consideration is the need to reference existing elements within the scripts.

More complex scripts (aggregating scripts) might need to access multiple resources (for examplenavigation, sidebar, footer, elements of a list) and do so by including the resource.

To do this you can use the sling:include("/<path>/<resource>") command. This willeffectively include the definition of the referenced resource, as in the following statement whichreferences an existing definition for rendering images:

%><sling:include resourceType="geometrixx/components/image/img"/><%

2.8.8 First Steps - an example for using Sling

An introduction the first steps of developing with Sling (and CRX) can be seen on http://dev.day.com/.

2.9 OSGI

OSGi defines an architecture for developing and deploying modular applications and libraries (itis also known as the Dynamic Module System for Java). OSGi containers allow you to break yourapplication into individual modules (are jar files with additional meta information and called bundlesin OSGi terminology) and manage the cross-dependencies between them with:

• services implemented within the container

• a contract between the container and your application

These services and contracts provide an architecture which enables individual elements todynamically discover each other for collaboration.

An OSGi framework then offers you dynamic loading/unloading, configuration and control of thesebundles - without requiring restarts.

Note

Full information on OSGi technology can be found at the OSGi Alliance TechnologyOverview.

Page 13: Cq5 Guide Developer

CQ in-depth

Page 9 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

In particular, their Basic Education page holds a collection of presentations and tutorials.

This architecture allows you to extend Sling with application specific modules. Sling, and thereforeCQ5, uses the Apache Felix implementation of OSGI (Open Services Gateway initiative). They areboth collections of OSGi bundles running within an OSGi framework.

This enables you to perform the following actions on any of the packages within your installation:

• install

• start

• stop

• update

• uninstall

• see the current status

• access more detailed information (e.g. symbolic name, version, location, etc) about the specificbundles

Page 14: Cq5 Guide Developer

Page 10 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

3 CQ5 WCM - Architecture andConcepts

CQ5 is Day's suite of products based on a standard JCR repository. WCM is the Web ContentManagement solution within CQ.

This section should be read in conjunction with the CQ5 WCM Architect Guide, which gives anoverview of the architecture and related concepts within CQ5.

3.1 Development objects

The following are of interest at the development level:

Node (and their properties)Nodes and their properties store content, CQ object definitions, rendering scripts and otherdata.

Nodes define the content structure, and their properties store the actual content and metadata.

Content nodes drive the rendering. Sling gets the content node from the incoming request. Theproperty sling:resourceType of this node points to the Sling rendering component to be used.

A node, which is a JCR name, is also called a resource in the Sling environment.

Note

In CQ, everything is stored in the repository.

WidgetIn CQ all user input is managed by widgets. These are often used to control the editing of apiece of content.

Dialogs are built by combining Widgets.

DialogA dialog is a special type of widget.

To edit content, CQ uses dialogs defined by the application developer. These combine a seriesof widgets to present the user with all fields and actions necessary to edit the related content.

Dialogs are also used for editing metadata, and by various administrative tools.

ComponentA software component is a system element offering a predefined service or event, and able tocommunicate with other components.

Within CQ a component is often used to render the content of a resource. When the resourceis a page, the component rendering it is called a Top-Level Component or a Pagecomponent.However, a component does not have to render content, nor be linked to a specific resource;for example, a navigation component will display information about multiple resources.

The definition of a component includes:,

• the code used to render the content

• a dialog for the user input and the configuration of the resulting content.

TemplateA template is the blueprint for a specific type of page. When creating a page in the siteadminthe user has to select a template. The new page is then created by copying this template.

Page 15: Cq5 Guide Developer

CQ5 WCM - Architecture and Concepts

Page 11 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

A template is a hierarchy of nodes that has the same structure as the page to be created, butwithout any actual content.

It defines the page component used to render the page and the default content (primary top-level content). The content defines how it is rendered as CQ is content-centric.

Page Component (Top-Level Component)The component to be used to render the page.

PageA page is an 'instance' of a template.

A page has a hierarchy node of type cq:Page and a content node of type cq:PageContent.The property sling:resourceType of the content node points to the Page Component used forrendering the page.

3.2 Structure within the repository

The following list gives an overview of the structure you will see within the repository.

Warning

Changes to this structure, or the files within it, should be made with care.

Changes are needed when you are developing, but you should take care that you fullyunderstand the implications of any changes you make.

Warning

You must not change anything in the libs/ path. For configuration and other changescopy the item in libs/ to apps/ and make any changes within apps/.

• /apps

Application related; includes component definitions specific to your website.

• /content

Content created for your website.

• /etc

Initialization and configuration information.

• /home

User and Group information.

• /libs

Libraries and definitions that belong to the core of CQ WCM.

• /tmp

Temporary working area.

• /var

Files that change and are updated by the system; such as audit logs, statistics, event-handling.

Page 16: Cq5 Guide Developer

Page 12 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

4 Development Tools4.1 Working with the CQ Development Environment (CQDE)

The CQ5 IDE (CQDE) provides a development platform for CQ5 applications. It is custom-builtspecifically for CQ and therefore recommended by Day.

CQDE is built on Eclipse RCP and EFS and comes as a set of Eclipse plugins.

4.1.1 Setting up CQDE

To set up CQDE, proceed as follows:

1. Ensure that CQ is installed and running.

2. Download the CQDE package.

3. Extract the package to your required installation location.

4. Double-click the executable.

5. Enter the location of your CQ5 installation; for example http://localhost:4502 for CQ5Quickstart.

6. Enter your username and password.

7. Click OK.

4.1.2 Configuring CQDE

If the location of your installation is different from above (for example, another host, port or contextpath) you also need to update the CRX server endpoint. This is the location where CQDE can findthe CRX WebDAV server. This can be done in the configuration section of the CQDE servlet whichis available on the Felix Management Console (http://localhost:4502/system/console/configMgr ).

When CQDE is started, it sends information about the users environment to CQ5; includingversion, OS and a profile ID. CQ5 stores this information under /etc/cqde/profiles, whereeach profile must have its own folder. The standard profile is default. The profile folder containsXSLT templates for generating CQDE project and classpath files, as well as additional settings.

- etc - cqde - profiles - [Name of Profile] (for example, default - the default profile that is distributed with CQ5) - project.xml.xslt (mandatory template for generating .project files) - classpath.xml.xslt (mandatory template for generating .classpath files) + mountPaths (optional multivalue string property defining the paths that should be mounted, if omitted root is mounted) + cqdeVersions (optional multivalue string property defining the CQDE5 versions that can use this profile) + cqdeOS (optional multivalue string property defining the operating systems that can use this profile)

4.2 How to Set Up the Development Environment with Eclipse

This document describes the process of setting up a local development environment for a simpleCQ5 project with Eclipse. It then describes how to integrate logic into the project through Javacoding and JSP scripting. Lastly, it points to open source software to enable collaborative andautomated developing.

Page 17: Cq5 Guide Developer

Development Tools

Page 13 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

The setup described here is an alternative among others and may vary from project to project.

The local development environment involves:

• A CQ5 installation that will act as your local environment.

• CRX Explorer within the CQ5 instance to create and edit nodes and properties within the CRXrepository.

• FileVault (VLT), a Day developed utility that maps the CRX repository to your file system.

• Eclipse to edit the project source on your local file system.

• Apache Maven to run local snapshot builds.

4.2.1 Creating the Project Structure in CQ5

This section describes the creation of a simple project structure in CQ5:

1. Install CQ5 on your machine. Please refer to the section called “Installing a CQ WCMInstance - Generic Procedure” for the detailed procedure. In the current context, CQ5 runslocally on port 4502.

If already installed then ensure it is running and connect.

2. In the CRX Explorer, create the project structure:

1. Under the /apps folder, create the nt:folder myApp.

2. Under the myApp folder, create the nt:folder components.

3. Under the myApp folder, create the nt:folder templates.

4. Under the myApp folder, create the nt:folder install.

3. In your browser, navigate to the Tools tab. Under designs, create the design page of yourapplication:

• Title: My Application Design Page.

• Name: myApp.

• Template: Design Page Template.

4.2.2 Installing FileVault (VLT)

FileVault (VLT) is a tool developed by Day that maps the content of a CRX instance to yourfile system. The VLT tool has similar functionalities to those of an SVN client, providing normalcheck in, check out and management operations, as well as configuration options for flexiblerepresentation of the project content.

To install VLT, follow the steps:

1. In your file system, go to <cq-installation-dir>/crx-quickstart/opt/filevault.The build is available in both tgz and zip formats.

2. Extract the archive.

3. Add <cq-installation-dir>/crx-quickstart/opt/filevault/vault-cli-<version>/bin to your environment PATH so that the command files vlt or vlt.bat areaccessed as appropriate. For example, <cq-installation-dir>/crx-quickstart/opt/filevault/vault-cli-1.1.2/bin

Page 18: Cq5 Guide Developer

Development Tools

Page 14 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

4. Open a command line shell and execute vlt --help. Make sure it displays the following helpscreen:

4.2.3 Installing Eclipse

Eclipse is open source software used to edit the project source locally on your file system. ApacheMaven is also open source software, used to run local snapshot builds: it compiles Java code andstores the compiled code in a jar file.

In this section, you will install Eclipse and a Maven plugin which embeds the Maven functionalitywithin Eclipse:

1. Download Eclipse - select the Eclipse IDE for Java EE Developers option.

2. Install Eclipse: extract from the downloaded zip file to your destination directory.

3. Start Eclipse:

a. Navigate to the directory into which you extracted the contents of the Eclipse installationzip file. For example C:\Program Files\Eclipse\.

b. Double-click on eclipse.exe (or eclipse.app) to start Eclipse.

4. Create a new workspace for your project and name it myApp.

5. Install the Maven plugin (m2) from Sonatype. Disable Maven SCM handler for Subclipse(Optional) and Maven Integration for AJDT (Optional).

6. After installation it is recommended to restart Eclipse.

4.2.4 Creating the Project Structure in Eclipse

In this section, you will create two Maven projects:

• one called UI (after User Interface) which contains the CQ5 project structure with the JSP scripts.

Page 19: Cq5 Guide Developer

Development Tools

Page 15 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

• the other called Core which contains the Java code (source and compiled). The compiled code isstored in a jar file.

The advantage of such a structure is that it adds modularity and autonomy to the logic of yourapplication because each jar file (bundle) can be managed separately.

4.2.4.1 Create the UI Maven Project

To create the UI Maven project, follow the steps:

1. In Eclipse open the Workbench.

2. Create the UI Maven project:

1. In the Menu bar, click File, select New, then Other... .

2. In the dialog, expand the Maven folder, select Maven Project and click Next.

3. Check the Create a simple project box and the Use default Workspacelocations box, then click Next.

4. Define the Maven project:

• Group Id: com.day.cq5.myapp

• Artifact Id: ui

• Name: CQ5 MyApp UI

• Description: This is the UI module

5. Click Finish.

3. Set the Java Compiler to version 1.5:

1. Right-click the ui project, select Properties.

2. Select Java Compiler and set following properties to 1.5:

• Compiler compliance level

• Generated .class files compatibility

• Source compatibility

3. Click OK.

4. In the dialog window, click Yes.

4. Create the filter.xml file which defines the content that will be exported by VLT:

1. In Eclipse, navigate to ui/scr/main and create the content folder.

2. Under content, create the META-INF folder.

3. Under META-INF, create the vault folder.

4. Under vault, create the filter.xml file.

5. In filter.xml, copy the following code to filter.xml:

<?xml version="1.0" encoding="UTF-8"?>

Page 20: Cq5 Guide Developer

Development Tools

Page 16 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

<!-- Defines which repository items are generally included--><workspaceFilter vesion="1.0"> <filter root="/apps/myApp" /> <filter root="/etc/designs/myApp" /></workspaceFilter>

6. Save the changes.

5. Check out the CQ5 content into your ui project with VLT:

1. From the system command line, navigate to the directory holding your Eclipseworkspace <eclipse>/<workspace>/myApp/ui/src/main/content.

2. Execute the command: vlt --credentials admin:admin co http://localhost:4502/crx

This command creates the folder jcr_root under <eclipse>/<workspace>/myApp/ui/src/main/content. This maps to the CRX root (/). Under jcr_root thefollowing files and folders are created, as defined in filter.xml:

• apps/myApp

• etc/designs/myApp

It also creates two files, config.xml and settings.xml in <eclipse>/<workspace>/myApp/ui/src/main/content/META-INF/vault. These are usedby VLT.

6. To enable Eclipse to map the file paths used in the JSP scripts, create a link to the appsfolder under ui:

1. Right-click ui, select New, then Folder.

2. In the dialog window, click Advanced and check the Link to folder in the filesystem box.

3. Click Browse, then specify <eclipse>/<workspace>/myApp/ui/src/main/content/jcr_root/apps.

4. Click OK.

5. Click Finish.

7. To enable Eclipse to identify the Java classes, methods and objects used in the JSP scripts,export the needed Java libraries from the CQ5 server to your file system and reference themin the ui project.

In this example, you will reference the following libraries:

• libs/cq/install stored in the CQ5 server

• libs/sling/install stored in the CQ5 server

• libs/wcm/install stored in the CQ5 server

• <cq-installation-dir>/crx-quickstart/server/lib/container stored inyour file system

Proceed as follows:

1. In your file system, create a CQ5 libraries folder called cq5libs. This folder can becreated anywhere.

Page 21: Cq5 Guide Developer

Development Tools

Page 17 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

2. Under cq5libs, create the folders: cq, sling and wcm.

3. From the system command line go to .../cq5libs/cq and execute vlt co http://localhost:4502/crx /libs/cq/install . to export the libraries stored under /libs/cq/install from the CQ5 server.

4. From the system command line go to .../cq5libs/sling and execute vlt co http://localhost:4502/crx /libs/sling/install . to export the libraries stored under /libs/sling/install from the CQ5 server.

5. From the system command line go to .../cq5libs/wcm and execute vlt co http://localhost:4502/crx /libs/wcm/install . to export the libraries stored under /libs/wcm/install from the CQ5 server.

6. In Eclipse, right-click the ui project, select Build Path, then Configure BuildPath. In the dialog select the Libraries tab.

7. Click Add External JARS..., navigate to .../cq5libs/cq/jcr_root, select allthe jar files and click Open.

8. Click Add External JARS..., navigate to .../cq5libs/sling/jcr_root, selectall the jar files and click Open.

9. Click Add External JARS..., navigate to .../cq5libs/wcm/jcr_root, select allthe jar files and click Open.

10. Click Add External JARS..., navigate to <cq-installation-dir>/crx-quickstart/server/lib/container, select all the jar files and click Open.

11. Click OK.

4.2.4.2 Create the Core Maven Project

To create the Core Maven project, follow the steps:

1. In Eclipse, create the Core Maven project:

1. In the Menu bar, click File, select New, then Other... .

2. In the dialog, expand the Maven folder, select Maven Project and click Next.

3. Check the Create a simple project box and the Use default Workspacelocations box, then click Next.

4. Define the Maven project:

• Group Id: com.day.cq5.myapp

• Artifact Id: core

• Name: CQ5 MyApp Core

• Description: This is the Core module

5. Click Finish.

2. Add the necessary plugins and dependencies to the core project:

1. Open the pom.xml file under core.

2. Copy-paste following code before the </project> tag:

Page 22: Cq5 Guide Developer

Development Tools

Page 18 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

<packaging>bundle</packaging>

<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>1.4.3</version> <extensions>true</extensions> <configuration> <instructions> <Export-Package> com.day.cq5.myapp.*;version=${pom.version} </Export-Package> </instructions> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>com.day.cq.wcm</groupId> <artifactId>cq-wcm-api</artifactId> <version>5.1.20</version> </dependency> <dependency> <groupId>com.day.cq</groupId> <artifactId>cq-commons</artifactId> <version>5.1.18</version> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.api</artifactId> <version>2.0.3-incubator-R708951</version> </dependency> </dependencies>

3. Save the changes.

3. Deploy the CQ5 specific artifacts as defined in the pom.xml (cq-wcm-api, cq-commons andorg.apache.sling.api) to the local Maven repository:

1. From the system command line go to <your-user-dir>/.m2/repository/com/day/cq/wcm/cq-wcm-api/5.1.20 (create the folders if they don't exist) and executevlt co http://localhost:4502/crx /libs/wcm/install/cq-wcm-api-5.1.20.jar . to export thelibrary from the CQ5 server.

2. From the system command line go to <your-user-dir>/.m2/repository/com/day/cq/cq-commons/5.1.18 (create the folders if they don't exist) and execute vltco http://localhost:4502/crx /libs/cq/install/cq-commons-5.1.18.jar . to export thelibrary from the CQ5 server.

Page 23: Cq5 Guide Developer

Development Tools

Page 19 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

3. From the system command line go to <your-user-dir>/.m2/repository/org/apache/sling/org.apache.sling.api/2.0.3-incubator-R708951 (createthe folders if they don't exist) and execute vlt co http://localhost:4502/crx /libs/sling/install/org.apache.sling.api-2.0.3-incubator-R708951.jar . to export the library fromthe CQ5 server.

Note

You don't need to perform this step if the three CQ5 artifacts are globally deployedfor the project on a Maven repository (e.g. using Apache Archiva).

4. Set the Java Compiler to version 1.5:

1. Right-click the core project, select Properties.

2. Select Java Compiler and set following properties to 1.5:

• Compiler compliance level

• Generated .class files compatibility

• Source compatibility

3. Click OK.

4. In the dialog window, click Yes.

5. Create the package com.day.cq5.myapp that will contain the Java classes under core/src/main/java:

1. Under core, right-click src/main/java, select New, then Package.

2. Name it com.day.cq5.myapp and click Finish.

4.2.5 Scripting with Eclipse and CQ5

When editing UI code use the following sequence:

• Create a template and a component with the CRX Explorer.

• Update the changes with VLT (export from the repository to your file system) .

• Create a component script (JSP) with Eclipse.

• Check in the changes from the file system into the repository with VLT.

The following example illustrates this process:

1. Create a new template with the CRX Explorer:

1. In the CRX Explorer, under /apps/myApp/templates, create a new template: Name:contentpage Type: cq:Template

2. Under the contentpage Node, edit the Property jcr:title and add as Value:MyApp Content Page Template

3. Under the contentpage Node, add a new Node: Name: jcr:content Type:cq:PageContent

4. Under the jcr:content Node, edit the Property sling:resourceType and add asValue: myApp/components/contentpage

Page 24: Cq5 Guide Developer

Development Tools

Page 20 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

5. Under the jcr:content Node, add a new Property: Name: personName Value:myName

2. Create a new component with the CRX Explorer:

• In the CRX Explorer, under /apps/myApp/components, create a new component:Name: contentpage Type: cq:Component

3. Use VLT to update the changes made from your repository to your file system, and thereforeEclipse:

1. From the system command line navigate to <eclipse>/<workspace>/myApp/ui/src/main/content/jcr_root.

2. Execute: vlt st --show-update to see the changes made on the repository.

3. Execute: vlt up to update the changes from the repository to your file system.

4. Create the component script (JSP) with Eclipse:

1. In Eclipse, navigate to ui/src/main/content/jcr_root/apps/myApp/components/contentpage.

2. Right-click contentpage, select New, then File.

3. In the dialog, name the file contentpage.jsp and click Finish.

4. Copy the following code into contentpage.jsp:

This is the contentpage component.

5. Save the changes.

5. With VLT check in the changes from the file system into the repository:

1. From the system command line navigate to <eclipse>/<workspace>/myApp/ui/src/main/content/jcr_root.

2. Execute: vlt st to see the changes made on the file system.

3. Execute: vlt add apps/myApp/components/contentpage/contentpage.jsp to add thecontentpage.jsp file to VLT control.

4. Execute: vlt ci to commit the contentpage.jsp file to the repository.

6. From CQ5 create a page based on this template. Open the page to make sure it displays thefollowing message:

This is the contentpage component.

Tip

It is possible to define the VLT commands as External Tools in Eclipse. This enables youto run the VLT commands from within Eclipse.

4.2.6 Java Developing with Eclipse and CQ5

When editing Core code use the following sequence:

• Create a Java class.

Page 25: Cq5 Guide Developer

Development Tools

Page 21 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

• Compile the Java class.

• Reference the jar file in the ui library.

• Embed the Java Class logic into the JSP script.

• Use VLT to check these changes to the JSP script (in the file system) into the repository.

• Use VLT to deploy the jar file (with the compiled class) from the file system into the repository.

The following example illustrates this process:

1. Create the Java class:

1. In Eclipse, under core/src/main/java, right-click the com.day.cq5.myapppackage, select New, then Class.

2. In the dialog window, name the Java Class HelloPerson and click Finish. Eclipsecreates and opens the file HelloPerson.java.

3. In HelloPerson.java replace the existing code with the following:

package com.day.cq5.myapp;

import com.day.cq.wcm.api.Page;

public class HelloPerson {

private Page personPage;

public static final String PN_PERSON_NAME = "personName";

public HelloPerson(Page personPage) {this.personPage = personPage;}

public String getHelloMessage() {String personName = personPage.getProperties().get(PN_PERSON_NAME).toString();

return personName != null ? personName : "--empty--";}

}

4. Save the changes.

2. Compile the Java class:

1. Right-click the core project, select Run As, then Maven Install.

2. Make sure that a new file core-0.0.1-SNAPSHOT.jar (containing the compiledclass) is created under core/target.

3. Reference this jar file in the ui library to enable the code completion when accessing thisclass with the JSP script:

1. In Eclipse, right-click the ui project, select Build Path, then Configure BuildPath. In the dialog select the Libraries tab.

2. Click Add JARS... and navigate to core/target, select the core-0.0.1-SNAPSHOT.jar file and click OK.

3. Click OK to close the dialog.

4. Embed the Java Class logic into the JSP script:

Page 26: Cq5 Guide Developer

Development Tools

Page 22 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

1. In Eclipse, open the JSP script contentpage.jsp in ui/src/main/content/jcr_root/apps/myApp/components/contentpage.

2. Replace the existing code with the following:

<%@ page import="com.day.cq5.myapp.HelloPerson" %><%@include file="/libs/wcm/global.jsp"%><%HelloPerson hello = new HelloPerson(currentPage);String msg = hello.getHelloMessage();%>Hello, <%= msg %>.</br></br>This is the contenpage component.

3. Save the changes.

5. With VTL check in the changes to the JSP script from the file system to the repository:

1. From the system command line navigate to <eclipse>/<workspace>/myApp/ui/src/main/content/jcr_root.

2. Execute: vlt st to see the changes made on the file system.

3. Execute: vlt ci to commit the modified contentpage.jsp file to the repository.

6. Deploy the jar file containing the compiled class from the file system into the repository withVLT:

1. In Eclipse, under core/target, copy the core-0.0.1-SNAPSHOT.jar file.

2. In Eclipse navigate to ui/scr/main/content/jcr_root/apps/myapp/installand paste the copied file.

3. From the system command line navigate to <eclipse>/<workspace>/myApp/ui/src/main/content/jcr_root.

4. Execute: vlt st to see the changes made on the file system.

5. Execute: vlt add apps/myApp/install/core-0.0.1-SNAPSHOT.jar to add the jar file toVLT control.

6. Execute: vlt ci to commit the jar file to the repository.

7. In your browser, refresh the CQ5 page to make sure it displays following message:

Hello, myName.

This is the contentpage component.

8. In CRX Explorer, change the value myName and make sure that the new value is displayedwhen you refresh the page.

4.2.7 Building collaborative and automated projects

This section points to three open source softwares which enhance the development of CQ5projects by adding collaboration and automation features:

• Subversion (SVN) to manage a central repository where all the developers involved in the projectcan commit and retrieve the code and the content they generate on their local instance.

• Apache Archiva to centrally store and retrieve the project libraries.

Page 27: Cq5 Guide Developer

Development Tools

Page 23 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

• Apache Continuum to automate the build process.

4.2.7.1 Collaboration with Subversion (SVN)

As the CQ5 repository can be mapped to your file system with VLT, it is now easy to set up acentral repository with SVN. This is used by all developers in the project as a place they cancommit, and retrieve, the code and content they generate on their local instances.

The setup of an SVN server is not covered in this document as many tutorials are already availableonline.

When VLT is in operation it creates .vlt files within the local directory structure. These .vlt files holdtimestamps and other VLT-specific information that should not be checked into the SVN repository.This can be prevented by adding .vlt to the ignore list of the local SVN setup. To do this you addthe following code to the local SVN setup file - settings.xml in the .subversion directory of youruser's HOME directory:

[miscellany]### Set global-ignores to a set of whitespace-delimited globs### which Subversion will ignore in its 'status' output, and### while importing or adding files and directories.global-ignores = .vlt

4.2.7.2 Central dependency management with Apache Archiva

Java libraries, called artifacts in Maven language, can be managed centrally through ApacheArchiva, an artifact repository that is used to store and retrieve the project artifacts. The setup ofArchiva is well detailed online and can be referenced during setup. The Archiva server requireslittle management outside that of configuring local developer accounts to obtain access to thesnapshots and full releases.

4.2.7.3 Build automation with Apache Continuum

Once the project content and code is centrally available through an SVN server, it is possible toautomate the build process and run the build on a daily basis (for example a nightly build). This isdone with Apache Continuum, a continuous integration server with the sole duty of providing buildmanagement of artifacts and releases.

The setup of Continuum is also well detailed online.

Page 28: Cq5 Guide Developer

Page 24 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

5 DesignerYou will need a design to define for your website.

Your design can be defined in the designs section of the Tools tab:

Here you can create the structure required to store the design and upload the cascaded stylesheets and images required.

Designs are stored under /etc/designs. The path to the design to be used for a website isspecified using the cq:designPath property of the jcr:content node.

Page 29: Cq5 Guide Developer

Page 25 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

6 Templates6.1 What are Templates?

A Template is used to create a Page and defines which components can be used within theselected scope. A template is a hierarchy of nodes that has the same structure as the page to becreated, but without any actual content.

Each Template will present you with a selection of components available for use.

• Templates are built up of Components;

• Components use, and allow access to, Widgets and these are used to render the Content.

6.2 Overview of templates

CQ WCM comes with several templates including a contentpage, redirect page, and home page.

Table 6.1. Templates within CQ5 (/apps/geometrixx/components and /libs/foundation/components)

Title Component Location Purpose

Home Page homepage geometrixx The Geometrixx home pagetemplate.

Content Page contentpage geometrixx The Geometrixx content pagetemplate.

Redirect redirect libs Redirect. Component and Template.

6.3 How Templates are structured

There are two aspects to be considered:

• the structure of the template itself

• the structure of the content produced when a template is used

6.3.1 The structure of a Template

A Template is created under a node of type cq:Template.

Page 30: Cq5 Guide Developer

Templates

Page 26 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Various properties can be set, in particular:

• jcr:title - title for the template; appears in the dialog when creating a page.

• jcr:description - description for the template; appears in the dialog when creating a page.

This node contains a jcr:content (cq:PageContent) node which be used as the basis for the contentnode of resulting pages; this references, using sling:resourceType, the component to be used forrendering the actual content of a new page.

This component is used to define the structure and design of the content when a new page iscreated.

Page 31: Cq5 Guide Developer

Templates

Page 27 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

6.3.2 The content produced by a Template

Templates are used to create Pages of type cq:Page (as mentioned earlier, a Page is a specialtype of Component). Each CQ WCM Page has a structured node jcr:content. This:

• is of type cq:PageContent

• is a structured node-type holding a defined content-definition

• has a property sling:resourceType to reference the component holding the sling scripts used forrendering the content

Page 32: Cq5 Guide Developer

Templates

Page 28 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

6.4 Developing Page Templates

CQ5 page templates are simply models used to create new pages. They can contain as little, or asmuch, initial content as needed, their role being to create the correct initial node structures, with therequired properties (primarily sling:resourceType) set to allow editing and rendering.

6.4.1 Creating a new Template (based on an existing template)

Needless to say a new template can be created completely from scratch, but often an existingtemplate will be copied and updated to save you time and effort. For example, the templates withinGeometrixx can be used to get you started.

1. Copy an existing template (preferably with a definition as close as possible to what you wantto achieve) to a new node.

Note

Templates are usually stored in /apps/<website-name>/templates/<template-name>.

2. Change the jcr:title of the new template node to reflect its new role. You can also update thejcr:description if appropriate.

3. Copy the component on which the template is based (this is indicated by thesling:resourceType property of the jcr:content node within the template) to create a newinstance.

Page 33: Cq5 Guide Developer

Templates

Page 29 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Note

Components are usually stored in /apps/<website-name>/components/<component-name>.

4. Update the jcr:title and jcr:description of the new component.

5. Replace the thumbnail.png if you want a new thumbnail picture to be shown in thetemplate selection list.

6. Update the sling:resourceType of the template's jcr:content node to reference the newcomponent.

7. Make any further changes to the functionality or design of the template and/or its underlyingcomponent.

Changes made to the /apps/<website>/templates/<template-name> node will affectthe template instance (as in the selection list).

Changes made to the /apps/<website>/components/<component-name> node willaffect the content page created when the template is used.

You can now create a page within your website using the new template.

6.5 Summary

Summary:

Location: /apps/<myapp>/templates

Root Node:

• <mytemplate> (cq:Template) - Hierarchy node of the template

Vital Properties:

• jcr:title - Template title, appears in the Create Page Dialog

• jcr:description - Template description, appears in the Create Page Dialog

Vital Child Nodes:

• jcr:content (cq:PageContent) - Content node for template instantiations

Vital Properties of Child Node jcr:content:

• sling:resourceType - Reference to the rendering component

The template is a blueprint of a specific type of page. To create a page the template must becopied (node-tree /apps/<myapp>/templates/<mytemplate>) to the corresponding position in thesite-tree (this is what happens if a page is created using the siteadmin). This copy action also givesthe page its initial content (usually Top-Level Content only) and the property sling:resourceType,the path to the page component that is used to render the page (everything in the child nodejcr:content).

Page 34: Cq5 Guide Developer

Page 30 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

7 Components7.1 What exactly is a Component?

Components:

• are modular units which realize specific functionality to present your content on your website

• are re-usable

• are developed as self-contained units within one folder of the repository

• have no hidden configuration files

• can contain other components

• run anywhere within any CQ system

• have a standardized user interface

• use widgets

As components are modular, you can develop a new component on your local instance, thendeploy this seamlessly to your test, then live environments.

Each CQ component:

• is a resource type

• is a collection of scripts that completely realize a specific function

• can function in "isolation"; this means either within CQ or a portal

Components included with CQ include:

• paragraph system

• header

• image, with accompanying text

• toolbar

Note

The functionality provided by Components and Widgets was implemented by the cfclibraries in Communiqué 4.

7.2 Default Components within CQ WCM

CQ WCM comes with a variety of out-of-the-box components that provide comprehensivefunctionality for website authors. These components and their usage within the installed"Geometrixx" website are a reference on how to implement and use components. The componentsare provided with all source code and can be used “as is” or as starting point for modified orextended components.

Using CRX, the default components can be found in the following locations:

Page 35: Cq5 Guide Developer

Components

Page 31 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

• /libs/foundation/components

• /apps/geometrixx/components

• /libs/collab/components

• /libs/collab/blog/components

• /libs/collab/calendar/components

• /libs/dam/components

• /libs/personalization/components

• /libs/replication/components

• /libs/search/components

• /libs/security/components

• /libs/tagging/components

For detailed information on all the default components, including those that are not available out-of-the-box in CQ WCM, see Chapter 4,

7.3 Components and their structure

7.3.1 Component definitions

As already mentioned, the definition of a component can be broken down into:

• CQ components are based on Sling

• CQ WCM components are located under /libs/foundation/components

• site specific components are located under /apps/<sitename>/components

• CQ WCM has the page component; this is a particular type of resource which is important forcontent management.

• CQ5 standard components are defined as cq:Component and have the elements:

• a list of jcr properties; these are variable and some may be optional though the basic structureof a component node, its properties and subnodes are defined by the cq:Component definition

• the dialog defines the interface allowing the user to configure the component

• the dialog (of type cq:Dialog) and cq:editConfig (of type cq:EditConfig) must bothbe defined as otherwise the component will not appear

• resources: define static elements used by the component

• scripts are used to implement the behavior of the resulting instance of the component

• thumbnail: image to be shown if this component is listed within the paragraph system

If we take the text component, we can see these elements:

Page 36: Cq5 Guide Developer

Components

Page 32 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Properties of particular interest include:

• jcr:title - title of the component; for example, appears in the component list within sidekick

• jcr:description - description for the component; again appears in the component list withinsidekick

• allowedChildren - components which are allowed as children

• allowedParents - components which can be specified as parents

• icon.png - graphics file to be used as an icon for the component

• thumbnail.png - graphics file to be used as a thumbnail for the component

Child nodes of particular interest include:

• cq:editConfig (cq:EditConfig) - this controls visual aspects; for example, it can definethe appearance of a bar or widget, or can add customized controls

• cq:childEditConfig(cq:EditConfig) - this controls the visual aspects for childcomponents that do not have their own definitions

• dialog (nt:unstructured) - defines the dialog for editing content of this component

• design_dialog (nt:unstructured) - specifies the design editing options for thiscomponent

7.3.1.1 Dialogs

Dialogs are a key element of your component as they provide an interface for authors to configureand provide input to that component.

Page 37: Cq5 Guide Developer

Components

Page 33 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Depending on the complexity of the component your dialog may need one or more tabs - to keepthe dialog short and to sort the input fields.

For example, you can create the dialog as cq:Dialog, which will provide a single tab - as in thetext component, or if you need multiple tabs, as with the textimage component, the dialog can bedefined as cq:TabPanel:

Within a dialog, a cq:WidgetCollection (items) is used to provide a base for either input fields(cq:Widget) or further tabs (cq:Widget). This hierarchy can be extended.

7.3.2 Component definitions and the content they create

If we create an instance of the Text paragraph (as above) on the <content-path>/Test.hmlpage:

Page 38: Cq5 Guide Developer

Components

Page 34 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

then we can see the structure of the content created within the repository:

In particular, if you look at the title:

Page 39: Cq5 Guide Developer

Components

Page 35 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

• the definition of /libs/foundation/components/text/dialog/items/title has theproperty name=./jcr:title

• within the content, this generates the property jcr:title holding the input Test Title.

The properties defined are dependent on the individual definitions, which although they can bemore complex than above, follow the same basic principles.

7.3.3 Component Hierarchy and Inheritance

Components within CQ are subject to 3 different hierarchies:

• Resource Type Hierarchy:

This is used to extend components using the property sling:resourceSuperType. This enablesthe component to inherit; for example a text component will inherit various attributes from thestandard component.

• scripts (resolved by Sling)

• dialogs

• descriptions (including thumbnail images, icons, etc)

• Container Hierarchy :

This is used to populate configuration settings to the child component and is most commonlyused in a parsys scenario.

For example, configuration settings for the edit bar buttons, control set layout (editbars, rollover),dialog layout (inline, floating) can be defined on the parent component and propagated to thechild components.

Configuration settings (related to edit functionality) in cq:editConfig and cq:childEditConfig arepropagated.

• Include Hierarchy

This is imposed at runtime by the sequence of includes.

This hierarchy is used by the Designer, which in turn acts as the base for various design aspectsof the rendering; including layout information, css information, the available components in aparsys among others.

7.3.4 Summary

The following summary applies for every component.

Summary:

Location: /apps/<myapp>/components

Root Node:

• <mycomponent> (cq:Component) - Hierarchy node of the component.

Vital Properties:

• jcr:title - Component title; for example, used as a label when the component islisted within the sidekick.

• jcr:description - Component description; for example, also shown in thecomponent list of the sidekick.

Page 40: Cq5 Guide Developer

Components

Page 36 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

• allowedChildren - Specifies the allowed child components.

• allowedParents - Specifies the allowed parent components.

• icon.png/thumbnail.png - Icon & thumbnail for this component.

Vital Child Nodes:

• cq:editConfig (cq:EditConfig) - Controls author UI aspects; for example, bar orwidget appearance, adds custom controls.

• cq:childEditConfig (cq:EditConfig) - Controls author UI aspects for childcomponents that do not define their own cq:editConfig.

• dialog (cq:Dialog) - Content editing dialog for this component.

• design_dialog (cq:Dialog) - Design editing for this component.

7.4 Developing Components

This section describes how to create your own components and add them to the paragraphsystem.

A quick way to get started is to copy an existing component and then make the changes you want.You can also use this method to edit existing components (although Day recommends that youback up the original component).

An example of how to develop a component is described in detail in Extending the Text and ImageComponent - An Example.

7.4.1 Developing a new component by adapting an existing component

To develop new components for CQ WCM based on existing component, you copy the componentand create a javascript file for the new component and store it in a location accessible to CQ5:

1. Create a new component folder in /apps/<website-name>/components/<MyComponent> by copying an existing component, such as the Textcomponent, and renaming it.

2. In the CRX Explorer, modify the jcr:description and jcr:title to reflect its new name.

Page 41: Cq5 Guide Developer

Components

Page 37 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

3. Open the new component folder and make the changes you require; also, delete anyextraneous information in the folder.

You can make changes such as:

• adding a new field in the dialog box

• replacing the .jsp file (name it after your new component)

• or completely reworking the entire component if you want

For example, if you take a copy of the standard Text component, you can add an additionalfield to the dialog box, then update the .jsp to process the input made there.

4. In the Content Explorer, navigate to the component and change the allowedParentsproperty to */parsys, which makes it available to the paragraph system.

Note

Either cq:editConfig node, dialog, or design_dialog node should be present andproperly initialized for the new component to appear.

5. Activate the new component in your paragraph system either by adding /apps/<website-name>/components/<MyComponent> to the /etc/designs/default/<website-name>/jcr:content/contentpage/parsys/components property in CRX or byfollowing the instructions in Adding new components to paragraph systems.

6. In CQ WCM, open a page in your web site and insert a new paragraph of the type you justcreated to make sure the component is working properly.

Note

To see timing statistics for page loading, you can use Ctrl-Shift-U - with ?debugClientLibs=true set in the URL.

7.4.2 Adding a new component to the paragraph system (design mode)

After the component has been developed, you add it to the paragraph system, which enablesauthors to select and use the component when editing a page.

1. Access a page within your authoring environment that uses the paragraph system; forexample <contentPath>/Test.html.

2. Switch to Design mode by either:

• adding ?cmsmode=design to the end of the URL and accessing again; for example<contextPath>/ Test.html?cmsmode=design.

• clicking Design in Sidekick

You are now in designmode and can edit the paragraph system:

3. Click Edit.

A list of components belonging to the paragraph system are shown (all those defined with theproperty allowedParents=*/parsys). Your new component is also listed.

The components can be activated (or deactivated) to determine which are offered to theauthor when editing a page.

Page 42: Cq5 Guide Developer

Components

Page 38 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

4. Activate your component, then return to normal edit mode to confirm that it is available foruse.

7.4.3 Extending the Text and Image Component - An Example

This section provides an example on how to extend the widely used text and image standardcomponent with a configurable image placement feature.

The extension to the text and image component allows editors to use all the existing functionality ofthe component plus have an extra option to specify the placement of the image either:

• on the left-hand side of the text (current behavior and the new default)

• as well as on the right-hand side

After extending this component, you can configure the image placement through the component'sdialog box.

The following techniques are described in this exercise:

• Copying existing component node and modifying its metadata

• Modifying the component's dialog, including inheritance of widgets from parent dialog boxes

• Modifying the component's script to implement the new functionality

7.4.3.1 Extending the existing textimage component

To create the new component, we use the standard textimage component as a basis and modifyit. We store the new component in the Geometrixx CQ WCM example application. To extend thetextimage component, go to the CRX Explorer (server name:port number/crx) and log in asadmin and then navigate to the Content Explorer.

1. Copy the standard textimage component from /libs/foundation/components/textimage into the Geometrixx component folder, /apps/geometrixx/components,using textimage as the target node name. (Copy the component by navigating to thecomponent, right-clicking and selecting Copy and browsing to the target directory.)

Page 43: Cq5 Guide Developer

Components

Page 39 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

2. To keep this example simple, navigate to the component you copied and delete all thesubnodes of the new textimage node except for the following ones:

• dialog definition: textimage/dialog

• component script: textimage/textimage.jsp

3. Edit the component metadata:

• Component name

• Set jcr:description to Text Image Component (Extended)

• Set jcr:title to Text Image (Extended)

• Component listing in the paragraph (parsys component) system (leave as is)

• Leave allowedParents defined as */parsys

• Group, where the component is listed in the sidekick (leave as is)

• Leave componentGroup set to General

• Parent component for the new component (the standard textimage component)

• Set sling:resourceSuperType to foundation/components/textimage

After these steps the component node looks like the following:

Page 44: Cq5 Guide Developer

Components

Page 40 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

4. Modify the component's dialog box to include the new option. The new component inheritsthe parts of the dialog box that are the same as in the original. The only addition we make isto extend the Advanced tab, adding an Image Position dropdown list, with options Leftand Right:

• Leave the textimage/dialog properties unchanged.

• Note how textimage/dialog/items has three subnodes, tab1 to tab3, representingthe three tabs of the textimage dialog box.

• For the first two tabs (tab1 and tab2):

• Change xtype to cqinclude (to inherit from the standard component).

• Add a pathParameter property with values /libs/foundation/components/textimage/dialog/items/tab1.infinity.json and /libs/foundation/components/textimage/dialog/items/tab2.infinity.json, respectively.

• Remove all other properties or subnodes.

• For tab3:

• Leave the properties and subnodes without changes

• Add a new field definition to tab3/items, node position of type cq:Widget

• Set the following properties (of type String) for the new tab3/items/position node

• name: ./imagePosition

• xtype: selection

• fieldLabel: Image Position

• type: select

• Add subnode position/options of type cq:WidgetCollection to represent thetwo choices for image placement, and under it create two nodes, o1 and o2 of typent:unstructured

• For node position/options/o1 set the properties: text to Left and value to left

• For node position/options/o2 set the properties: text to Right and value toright

Image position is persisted in content as the imagePosition property of the noderepresenting textimage paragraph.

Page 45: Cq5 Guide Developer

Components

Page 41 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

After these steps, the component dialog box looks like this:

5. Extend the component script, textimage.jsp, with extra handling of the new parameter.

• Open the /apps/geometrixx/components/textimage/textimage.jsp script forediting.

• We are going to manipulate the style of the <div class="image"> tag, generated by thecomponent, to float the image to the right. It is located in the following area of the code:

Image img = new Image(resource, "image"); if (img.hasContent() || WCMMode.fromRequest(request) == WCMMode.EDIT) {%><div class="image"><% img.loadStyleData(currentStyle);

We are going to replace the emphasized code fragment %><div class="image"><%with new code generating a custom style for this tag.

• Copy the following code fragment, and replace the %><div class="image"><% line withit:

// todo: add new CSS class for the 'right image' instead of using // the style attribute String style=""; if (properties.get("imagePosition", "left").equals("right")) { style = "style=\"float:right\""; } %><div <%= style %> class="image"><%

Note that for simplicity we are hard-coding the style to the HTML tag. The proper way to doit would be to add a new CSS class to the application styles and just add the class to thetag in the code in the case of a right-aligned image.

• The code fragment, after the change, should look like this (new code emphasized):

Image img = new Image(resource, "image"); if (img.hasContent() || WCMMode.fromRequest(request) == WCMMode.EDIT) { // todo: add new CSS class for the 'right image' instead of using // the style attribute

Page 46: Cq5 Guide Developer

Components

Page 42 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

String style=""; if (properties.get("imagePosition", "left").equals("right")) { style = "style=\"float:right\""; } %><div <%= style %> class="image"><% img.loadStyleData(currentStyle);

• Save the script to the repository.

6. The component is ready to test.

7.4.3.2 Checking the new component

After the component has been developed, you can add it to the paragraph system, which enablesauthors to select and use the component when editing a page. These steps allow you to test thecomponent.

1. Open a page in Geometrixx; for example, English/Company

2. Switch to design mode by clicking Design in Sidekick

3. Edit the paragraph system design by clicking Edit on the paragraph system in the middle ofthe page. A list of components, which can be placed in the paragraph system are shown, andit should include your newly developed component, Text Image (Extended). Activate itfor the paragraph system by selecting it and clicking OK.

4. Switch back to the editing mode.

5. Add the Text Image (Extended) paragraph to the paragraph system, initialize text and imagewith sample content. Save and you should see the default rendering of Text and Imagecomponent:

6. Open the dialog of the text and image paragraph, and change the Image Position on theAdvanced tab to Right, and click OK to save the changes.

Page 47: Cq5 Guide Developer

Components

Page 43 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

7. You see the paragraph rendered with the image on the right:

8. The component is now ready to use.

The component stores its content in a paragraph on the Company page. The following screenshotshows how our new configuration parameter is persisted in the repository, with the noderepresenting the paragraph we have just created.

Page 48: Cq5 Guide Developer

Components

Page 44 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

The textimage/imagePosition parameter represents the position of the image for thisparagraph on /content/geometrixx/en/company page.

7.5 Further Development of Specific Components and Tools

7.5.1 Developing the Bulk Editor

This section describes how to develop the bulk editor tool and how to extend the Product Listcomponent, which is based on the bulk editor.

7.5.1.1 Bulk editor query parameters

When working with the bulk editor, there are several query parameters that you can add tocall the bulk editor with a specific configuration. If you want the bulk editor to always be usedwith a certain configuration, for example, as in the Product List component, then you need tomodify bulkeditor.jsp (located in/libs/wcm/bulkeditor/bulkeditor.jsp)or createa component with the specific configuration. Changes made using query parameters are notpermanent.

For example if you type the following in your browser's URL:

http://<servername>:<port_number>/etc/importers/bulkeditor.html?rootPath=/content/geometrixx/en&queryParams=geometrixx&initialSearch=true&hrp=true

the bulk editor displays without the root path field. hrp=true hides the field. hrp=false displaysit (the default value).

The following is a list of the bulk editor query parameters:

accepted parametersIf name is null, short name is read from request.

search root pathString rootPath = getString(request,"rootPath","rp");

Page 49: Cq5 Guide Developer

Components

Page 45 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

search queryString queryParams = getString(request,"queryParams","qp");

is content mode enabledProperties are read on jcr:content node and not on search result node

Boolean contentMode = getBoolean(request,"contentMode","cm");

searched properties (checked values from colsSelection displayed as checkboxes)String[] colsValue = getStringArray(request,"colsValue","cv");

extra searched properties (displayed in a comma-separated text field)String[] extraCols = getStringArray(request,"extraCols","ec");

is query performed on page loadBoolean initialSearch = getBoolean(request,"initialSearch","is");

searched properties selection (displayed as checkboxes)String[] colsSelection = getStringArray(request,"colsSelection","cs");

show only the grid and not the search panelNote: Be sure to set initialSearch to true

Boolean showGridOnly = getBoolean(request,"showGridOnly","sgo");

on load, search panel is collapsedBoolean searchPanelCollapsed =getBoolean(request,"searchPanelCollapsed","spc");

hide root path fieldBoolean hideRootPath = getBoolean(request,"hideRootPath","hrp");

hide query fieldBoolean hideQueryParams = getBoolean(request,"hideQueryParams","hqp");

hide content mode fieldBoolean hideContentMode = getBoolean(request,"hideContentMode","hcm");

hide cols selection fieldBoolean hideColsSelection =getBoolean(request,"hideColsSelection","hcs");

hide extra cols fieldBoolean hideExtraCols = getBoolean(request,"hideExtraCols","hec");

hide search buttonBoolean hideSearchButton =getBoolean(request,"hideSearchButton","hsearchb");

hide save buttonBoolean hideSaveButton =getBoolean(request,"hideSaveButton","hsavep");

hide export buttonBoolean hideExportButton =getBoolean(request,"hideExportButton","hexpb");

hide import buttonBoolean hideImportButton =getBoolean(request,"hideImportButton","hib");

hide grid search result number textBoolean hideResultNumber =getBoolean(request,"hideResultNumber","hrn");

Page 50: Cq5 Guide Developer

Components

Page 46 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

hide grid insert buttonBoolean hideInsertButton =getBoolean(request,"hideInsertButton","hinsertb");

hide grid delete buttonBoolean hideDeleteButton =getBoolean(request,"hideDeleteButton","hdelb");

hide grid "path" columnBoolean hidePathCol = getBoolean(request,"hidePathCol","hpc");

7.5.1.2 Developing a Bulk Editor-based component: the Product Listcomponent

This section provides an overview of how to use the bulk editor and gives a description of theexisting Geometrixx component based on the bulk editor: the Product List component.

The Product List component lets users display and edit a table of data. For example, you can usethe Product List component to represent products in a catalog. The information is presented in astandard HTML table and any editing is performed in the Edit dialog, which contains a BulkEditorwidget. (This Bulk Editor is exactly the same as the one accessible at /etc/importers/bulkeditor.html (or through the Tools menu)). The Product List component has beenconfigured for specific, limited bulk editor functionality. Every part of the bulk editor (or componentsderived from the bulk editor) can be configured.

With the bulk editor, you can add, modify, delete, filter, and export the rows, save modifications,and import a set of rows. Every row is stored as a node under the Product List component instanceitself. Every cell is a property of each node. This is a design choice and it can easily be changed,for example, you could store nodes somewhere else in the repository. The query servlet's role is toreturn the list of the nodes to display; the search path is defined as a Product List instance.

The source code of the Product List component is available in the repository at path /apps/geometrixx/components/productlist and is composed of several parts like all CQ5components:

• HTML rendering: the rendering is done in a JSP file (\apps\geometrixx\components\productlist\productlist.jsp). JSP reads the subnodes of the current Product Listcomponent and displays each of them as a row of an HTML table.

• Edit dialog, which is where you define the Bulk Editor configuration. Configure the dialog tomatch the needs of the component: columns available and possible actions performed onthe grid or on the search. See bulk editor configuration properties for information on all of theconfiguration properties.

Here is an XML representation of the repository nodes:

<editorjcr:primaryType="cq:Widget"colsSelection="[CatalogCode,GroupId,SellingSku,ProductName,Attribute1,Attribute2,Attribute3,Attribute4]"colsValue="[CatalogCode,GroupId,SellingSku,ProductName,Attribute1,Attribute2,Attribute3,Attribute4]"contentMode="false"exportURL="/etc/importers/bulkeditor/export.tsv"hideColsSelection="false"hideContentMode="true"hideDeleteButton="false"hideExportButton="false"hideExtraCols="true"hideImportButton="false"hideInsertButton="false"hidePathCol="true"hideRootPath="true"hideSaveButton="false"hideSearchButton="false"importURL="/etc/importers/bulkeditor/import"

Page 51: Cq5 Guide Developer

Components

Page 47 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

initialSearch="true"insertedResourceType="geometrixx/components/productlist/sku"queryParams=""queryURL="/etc/importers/bulkeditor/query.json"xtype="bulkeditor"> <saveButton jcr:primaryType="nt:unstructured" text="Save modifications"/> <searchButton jcr:primaryType="nt:unstructured" text="Apply filter"/> <queryParamsInput jcr:primaryType="nt:unstructured" fieldDescription="Enter here your filters" fieldLabel="Filters"/> <searchPanel jcr:primaryType="nt:unstructured" height="200"> <defaults jcr:primaryType="nt:unstructured" labelWidth="150"/> </searchPanel> <grid jcr:primaryType="nt:unstructured" height="275"/> <store jcr:primaryType="nt:unstructured"> <sortInfo jcr:primaryType="nt:unstructured" direction="ASC" field="Attribute2"/> </store> <colModel jcr:primaryType="nt:unstructured" width="150"/> <colsMetadata jcr:primaryType="nt:unstructured"> <CatalogCode jcr:primaryType="nt:unstructured" cellStyle="background-color: #EDEDED;"/> <GroupId jcr:primaryType="nt:unstructured" cellStyle="background-color: #8080FE;"/> <ProductName jcr:primaryType="nt:unstructured" cellStyle="background-color: #FFCC99;"/> <SellingSku jcr:primaryType="nt:unstructured" cellCls="productlist-cell-sellingSku"/> <Selection> jcr:primaryType="nt:unstructured" checkbox="true" forcedPosition="0"/> </colsMetadata></editor>

7.5.1.2.1 Bulk Editor configuration properties

Every part of the bulk editor can be configured. The following table lists all the configurationproperties for the bulk editor.

Table 7.1. Bulk Editor Configuration Properties

Property name Definition

rootPath Search root path

queryParams Search query

contentMode True to enable content mode: properties are read on jcr:contentnode and not on search result node

colsValue

Page 52: Cq5 Guide Developer

Components

Page 48 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Property name Definition

Searched properties (checked values from colsSelection displayedas checkboxes)

extraCols Extra searched properties (displayed in a textfield commaseparated)

initialSearch True to perform query on page load

colsSelection Searched properties selection (displayed as checkboxes)

showGridOnly True to show only the grid and not the search panel (do not forgetto set the initialSearch to true)

searchPanelCollapsed True to collapse search panel by default

hideRootPath Hide root path field

hideQueryParams Hide query field

hideContentMode Hide content mode field

hideColsSelection Hide cols selection field

hideExtraCols Hide extra cols field

hideSearchButton Hide search button

hideSaveButton Hide save button

hideExportButton Hide export button

hideImportButton Hide import button

hideResultNumber Hide grid search result number text

hideInsertButton Hide grid insert button

hideDeleteButton Hide grid delete button

hidePathCol Hide grid "path" column

queryURL Path to query servlet

exportURL Path to export servlet

importURL Path to import servlet

insertedResourceType Resource type added to node when a row is inserted

saveButton Save button widget config

searchButton Search button widget config

exportButton Export button widget config

importButton Import button widget config

searchPanel Search panel widget config

grid Grid widget config

store Store config

colModel Grid column model config

rootPathInput rootPath widget config

queryParamsInput queryParams widget config

contentModeInput contentMode widget config

colsSelectionInput colsSelection widget config

extraColsInput extraCols widget config

colsMetadata Column metadata config. Possible properties are (applied to allcells of the column):

Page 53: Cq5 Guide Developer

Components

Page 49 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Property name Definition

• cellStyle: html style

• cellCls: css class

• readOnly: true to not being able to change value

• checkbox: true to define all cells of the column as checkboxes(true/false values)

• forcedPosition: integer value to specify where column must beplaced in grid (between 0 and number of colums-1)

7.5.1.2.2 Query servlet

By default, the Query servlet can be found at /libs/wcm/bulkeditor/json.java. You canconfigure another path to retrieve the data.

The Query servlet works as follows: it receives a GQL query and the columns to return, computesthe results, and sends the results back to the bulk editor as a JSON stream.

In the Product List component case, the two parameters sent to the Query servlet are as follows:

• query: "path:/content/geometrixx/en/customers/jcr:content/par/productlistaFilter"

• cols: "CatalogCode,GroupId,SellingSku,ProductName"

and the JSON stream returned is as follows:

{ hits: [{jcr:path: "/content/geometrixx/en/customers/jcr:content/par/productlist/1243436455359"CatalogCode: "CC1"GroupId: "GI1"SellingSku: "SS1"ProductName: "PN1" },{jcr:path: "/content/geometrixx/en/customers/jcr:content/par/productlist/1243436455361"CatalogCode: "CC2"GroupId: "GI2"SellingSku: "SS2"ProductName: "PN2" }], results: 2}

Each hit corresponds to one node and its properties and is displayed as a row in the grid.

For example, a query could be

• query: "path /content/brand/ chair"

• cols: "nameID,sku,catalogCode…"

You can extend the Query servlet to return a complex inheritance model or return nodes storedat a specific logic place. The Query servlet can be used to do any kind of complex computation.The grid can then display rows that are an aggregate of several nodes in the repository. Themodification and the saving of these rows must in that case be managed by the Save Servlet.

Page 54: Cq5 Guide Developer

Components

Page 50 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

7.5.1.2.3 Save servlet

Currently, each row is a node and the path of this node is stored in the row record. The Bulk Editorkeeps the link between the row and the node because of the jcr path. When a user edits the grid, alist of all of the modifications is built. When a user clicks Save, a POST query is sent to each pathwith the updated properties values. This is the basis of the Sling concept and it works well if eachcell is a property of the node. But because the Query servlet makes inheritance computation, thismodel cannot work: a property returned by the Query servlet can be inherited from another node.

The Save servlet concept is that the modifications are not directly posted to each node but thatthey are posted to one servlet that does the saving job. This gives this servlet the possibility toanalyze the modifications and save the properties on the right node.

Each updated property is sent to servlet in this format:

Parameter name: "jcr path"/"property name"

Value: new value

Example:

/content/brand/season/fall/groups/group1/sku1/catalogCode = 123456

This servlet should know where the catalogCode property is stored.

A default Save servlet implementation is available (/libs/wcm/bulkeditor/save/POST.jsp) and is in use in the ProductList component. It takes all parameters received (format "jcrpath"/"property name") and writes properties on nodes using the JCR API. It also creates node ifthey do not exist (grid inserted rows). Do not use the default code as is; the default code providedin this file re-implements what the server does natively (a POST on "jcr path"/"property name")and therefore is only a good starting point for building a Save servlet that will manage a propertyinheritance model.

7.5.1.2.4 Metadata configuration

You can configure metadata in the following ways:

• CSS and read-only columns

• Checkbox and forced position

7.5.1.2.4.1 CSS and read-only columns

The bulk editor has three column configurations:

• Cell CSS class name (cellCls): a CSS class name that is added on each cell of the configuredcolumn.

• Cell style (cellStyle): an HTML style that is added on each cell of the configured column.

• Read only (readOnly): read only is set for each cell of the configured column.

Configuration must be defined like this:

"colsMetadata": {"Column name": { "cellStyle": "html style", "cellCls": "CSS class", "readOnly": true/false}}

This example can be found in the productlist component (/apps/geometrixx/components/productlist/dialog/items/editor/colsMetadata):

Page 55: Cq5 Guide Developer

Components

Page 51 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

<colsMetadata jcr:primaryType="nt:unstructured"> <CatalogCode jcr:primaryType="nt:unstructured" cellStyle="background-color: #EDEDED;"/> <GroupId jcr:primaryType="nt:unstructured" cellStyle="background-color: #8080FE;"/> <ProductName jcr:primaryType="nt:unstructured" cellStyle="background-color: #FFCC99;"/> <SellingSku jcr:primaryType="nt:unstructured" cellCls="productlist-cell-sellingSku"/></colsMetadata>

7.5.1.2.4.2 Checkbox

If the checkbox configuration property is set to true, then all the cells of the columns are renderedas checkboxes. A checked box sends true to server Save servlet, false otherwise. In the headermenu, you can also select all and select none. These options are enabled if the selectedheader is the header of a checkbox column.

This example can be found in the productlist component (/apps/geometrixx/components/productlist/dialog/items/editor/colsMetadata): selection column contains only checkboxes and is always thefirst column.

<colsMetadata jcr:primaryType="nt:unstructured"> <CatalogCode jcr:primaryType="nt:unstructured" cellStyle="background-color: #EDEDED;"/> <GroupId jcr:primaryType="nt:unstructured" cellStyle="background-color: #8080FE;"/> <ProductName jcr:primaryType="nt:unstructured" cellStyle="background-color: #FFCC99;"/> <SellingSku jcr:primaryType="nt:unstructured" cellCls="productlist-cell-sellingSku"/> <Selection jcr:primaryType="nt:unstructured" checkbox="true" forcedPosition="0"/> </colsMetadata>

7.5.1.2.4.3 Forced position

Forced position (forcedPosition) metadata lets you specify where the column must always beplaced within the grid: 0 is the first place and <number of columns>-1 is the last position. Anyother value is ignored.

<colsMetadata jcr:primaryType="nt:unstructured"> <CatalogCode jcr:primaryType="nt:unstructured" cellStyle="background-color: #EDEDED;"/> <GroupId jcr:primaryType="nt:unstructured" cellStyle="background-color: #8080FE;"/> <ProductName jcr:primaryType="nt:unstructured" cellStyle="background-color: #FFCC99;"/> <SellingSku jcr:primaryType="nt:unstructured" cellCls="productlist-cell-sellingSku"/> <Selection jcr:primaryType="nt:unstructured" checkbox="true" forcedPosition="0"/>

Page 56: Cq5 Guide Developer

Components

Page 52 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

</colsMetadata>

7.6 Scripts

JSP Scripts or Servlets are usually used to render components.

According to the request processing rules of Sling the name for the default script is<componentname>.jsp.

7.6.1 global.jsp

The JSP script file global.jsp is used to provide quick access to specific objects (i.e. to accesscontent) to any JSP script file used to render a component.

Therefore global.jsp should be included in every component rendering JSP script where one ormore of the objects provided in global.jsp are used.

7.6.1.1 Function of global.jsp, used APIs and Taglibs

The following lists the most important objects provided from the default global.jsp (/libs/wcm/global.jsp)

Summary:

• <cq:defineObjects />

• slingRequest - The wrapped Request Object (SlingHttpServletRequest).

• slingResponse - The wrapped Response Object (SlingHttpServletResponse).

• resource - The Sling Resource Object (slingRequest.getResource();).

• resourceResolver - The Sling Resource Resolver Object(slingRequest.getResoucreResolver();).

• currentNode - The resolved JCR node for the request.

• log - The Default logger ().

• sling - The Sling script helper.

• properties - The properties of the addressed resource (resource.adaptTo(ValueMap.class);).

• pageProperties - The properties of the page of the addressed resource.

• pageManager - The page manager for accessing CQ content pages(resourceResolver.adaptTo(PageManager.class);).

• component - The component object of the current CQ5 component..

• designer - The designer object for retrieving design information(resourceResolver.adaptTo(Designer.class);).

• currentDesign - The design of the addressed resource.

• currentStyle - The style of the addressed resource.

7.6.1.2 Accessing Content

There are three methods to access content in CQ5 WCM:

• Via the properties object introduced in global.jsp:

Page 57: Cq5 Guide Developer

Components

Page 53 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

The properties object is an instance of a ValueMap (see Sling API) and contains all properties ofthe current resource.

Example: String pageTitle = properties.get("jcr:title", "no title"); usedin the rendering script of a page component.

Example: String paragraphTitle = properties.get("jcr:title", "no title");used in the rendering script of a standard paragraph component.

• Via the currentPage object introduced in global.jsp:

The currentPage object is an instance of a page (see CQ5 API). The page class provides somemethods to access content.

Example: String pageTitle = currentPage.getTitle();

• Via currentNode object introduced in global.jsp:

The currentNode object is an instance of a node (see JCR API). The properties of a node can beaccessed by the getProperty() method.

Example: String pageTitle = currentNode.getProperty("jcr:title");

Note

Day does not recommend using the JCR API directly in CQ5 if not really necessary; CQ5is a Sling Application and therefore we deal with resources and not nodes.

7.6.2 JSP Tag Libraries

The CQ and Sling tab libraries give you access to specific functions for use in the JSP script ofyour templates and components.

7.6.2.1 CQ Tag Library

The CQ tag library contains helpful CQ functions.

To use the CQ Tag Library in your script, the script must start with the following code:

<%@taglib prefix="cq" uri="http://www.day.com/taglibs/cq/1.0" %>

Note

When the /libs/wcm/global.jsp file is included in the script, the cq taglib isautomatically declared.

Tip

When you develop the jsp script of a CQ5 component, it is recommended to includefollowing code at the top of the script:

<%@include file="/libs/wcm/global.jsp"%>

It declares the sling, cq and jstl taglibs and exposes the regularly used scripting objectsdefined by the <cq:defineObjects /> tag. This shortens and simplifies the jsp code of yourcomponent.

7.6.2.1.1 <cq:setContentBundle>

The <cq:setContentBundle> tag creates an i18n localization context and stores it in thejavax.servlet.jsp.jstl.fmt.localizationContext configuration variable.

Page 58: Cq5 Guide Developer

Components

Page 54 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

It has the following attribute:

languageThe language of the locale for which to retrieve the resource bundle.

The "content bundle" can be simply used by standard JSTL <fmt:message> tags. The lookup ofmessages by keys is two-fold:

1. First, the JCR properties of the underlying resource that is currently rendered are searched fortranslations. This allows you to define a simple component dialog to edit those values.

2. If the node does not contain a property named exactly like the key, the fallback is to load aresource bundle from the sling request (SlingHttpServletRequest.getResourceBundle(Locale)).The language or locale for this bundle is defined this way:

a. First, if the parameter language of the<cq:setContentBundle> tag is set, this is used.

b. Otherwise, the locale of the page is looked up. This is defined by the LanguageManager ofCQ5 (language copy function), which is typically taken from the page path (eg. the path /content/site/en/some/page produces the "en" locale).

c. Finally, if there is no page language defined, the default locale of the current request is used,which is equivalent to calling request.getResourceBundle(null).

Example:

<%@include file="/libs/wcm/global.jsp"%><%%><%@ page import="com.day.cq.wcm.foundation.forms.ValidationInfo, com.day.cq.wcm.foundation.forms.FormsConstants, com.day.cq.wcm.foundation.forms.FormsHelper, org.apache.sling.api.resource.Resource, org.apache.sling.api.resource.ResourceUtil, org.apache.sling.api.resource.ValueMap" %><%%><cq:setContentBundle/>

7.6.2.1.2 <cq:include>

The <cq:include> tag includes a resource into the current page.

It has the following attributes:

flushA boolean defining whether to flush the output before including the target.

pathThe path to the resource object to be included in the current request processing. If this path isrelative it is appended to the path of the current resource whose script is including the givenresource. Either path and resourceType, or script must be specified.

resourceTypeThe resource type of the resource to be included. If the resource type is set, the path must bethe exact path to a resource object: in this case, adding parameters, selectors and extensionsto the path is not supported.

If the resource to be included is specified with the path attribute that cannot be resolved to aresource, the tag may create a synthetic resource object out of the path and this resource type.

Either path and resourceType, or script must be specified.

scriptThe jsp script to include. Either path and resourceType, or script must be specified.

Page 59: Cq5 Guide Developer

Components

Page 55 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

ignoreComponentHierarchyA boolean controlling whether the component hierarchy should be ignored for script resolution.If true, only the search paths are respected.

Example:

<%@taglib prefix="cq" uri="http://www.day.com/taglibs/cq/1.0" %><%%><div class="center"> <cq:include path="trail" resourceType="foundation/components/breadcrumb" /> <cq:include path="title" resourceType="foundation/components/title" /> <cq:include script="redirect.jsp"/> <cq:include path="par" resourceType="foundation/components/parsys" /></div>

Note

Should you use <%@ include file="myScript.jsp" %> or <cq:include script="myScript.jsp"%> to include a script?

• The <%@ include file="myScript.jsp" %> directive informs the JSP compiler to includea complete file into the current file. It is as if the contents of the included file werepasted directly into the original file.

• With the <cq:include script="myScript.jsp" %> directive, the file is included at runtime.

Note

Should you use <cq:include> or <sling:include>?

• When developing CQ5 components, Day recommends that you use <cq:include>.

• <cq:include> allows you to directly include script files by their name when using thescript attribute. This takes component and resource type inheritance into account, andis often simpler than strict adherence to Sling's script resolution using selectors andextensions.

7.6.2.1.3 <cq:defineObjects>

The <cq:defineObjects> tag exposes the following, regularly used, scripting objects which can bereferenced by the developer. It also exposes the objects defined by the <sling:defineObjects> tag.

componentContextthe current component context object of the request(com.day.cq.wcm.api.components.ComponentContext interface).

componentthe current CQ5 component object of the current resource(com.day.cq.wcm.api.components.Component interface).

currentDesignthe current design object of the current page (com.day.cq.wcm.api.designer.Design interface).

currentPagethe current CQ WCM page object (com.day.cq.wcm.api.Page interface).

currentStylethe current style object of the current cell (com.day.cq.wcm.api.designer.Style interface).

designerthe designer object used to access design information (com.day.cq.wcm.api.designer.Designerinterface).

Page 60: Cq5 Guide Developer

Components

Page 56 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

editContextthe edit context object of the CQ5 component (com.day.cq.wcm.api.components.EditContextinterface).

pageManagerthe page manager object for page level operations (com.day.cq.wcm.api.PageManagerinterface).

pagePropertiesthe page properties object of the current page (org.apache.sling.api.resource.ValueMap).

propertiesthe properties object of the current resource (org.apache.sling.api.resource.ValueMap).

resourceDesignthe design object of the resource page (com.day.cq.wcm.api.designer.Design interface).

resourcePagethe resource page object (com.day.cq.wcm.api.Page interface).

It has the following attributes:

requestNameinherited from sling

responseNameinherited from sling

resourceNameinherited from sling

nodeNameinherited from sling

logNameinherited from sling

resourceResolverNameinherited from sling

slingNameinherited from sling

componentContextNamespecific to wcm

editContextNamespecific to wcm

propertiesNamespecific to wcm

pageManagerNamespecific to wcm

currentPageNamespecific to wcm

resourcePageNamespecific to wcm

Page 61: Cq5 Guide Developer

Components

Page 57 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

pagePropertiesNamespecific to wcm

componentNamespecific to wcm

designerNamespecific to wcm

currentDesignNamespecific to wcm

resourceDesignNamespecific to wcm

currentStyleNamespecific to wcm

Example:

<%@page session="false" contentType="text/html; charset=utf-8" %><%%><%@ page import="com.day.cq.wcm.api.WCMMode" %><%%><%@taglib prefix="cq" uri="http://www.day.com/taglibs/cq/1.0" %><%%><cq:defineObjects/>

Note

When the /libs/wcm/global.jsp file is included in the script, the <cq:defineObjects /> tag is automatically included.

7.6.2.1.4 <cq:requestURL>

The <cq:requestURL> tag writes the current request URL to the JspWriter. The two tags<cq:addParam> and <cq:removeParam> may be used inside the body of this tag to modify thecurrent request URL before it is written.

It allows you to create links to the current page with varying parameters. For example, it enablesyou to transform the request:

mypage.html?mode=view&query=something into mypage.html?query=something.

The use of addParam or removeParam only changes the occurence of the given parameter, allother parameters are unaffected.

<cq:requestURL> does not have any attribute.

Examples:

<a href="<cq:requestURL><cq:removeParam name="language"/></cq:requestURL>">remove filter</a>

<a title="filter results" href="<cq:requestURL><cq:addParam name="language" value="${bucket.value}"/></cq:requestURL>">${label} (${bucket.count})</a>

7.6.2.1.5 <cq:addParam>

The <cq:addParam> tag adds a request parameter with the given name and value to the enclosing<cq:requestURL> tag.

It has the following attributes:

namename of the parameter to be added

Page 62: Cq5 Guide Developer

Components

Page 58 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

valuevalue of the parameter to be added

Example:

<a title="filter results" href="<cq:requestURL><cq:addParam name="language" value="${bucket.value}"/></cq:requestURL>">${label} (${bucket.count})</a>

7.6.2.1.6 <cq:removeParam>

The <cq:removeParam> tag removes a request parameter with the given name and value fromthe enclosing <cq:requestURL> tag. If no value is provided all parameters with the given name areremoved.

It has the following attributes:

namename of the parameter to be removed

Example:

<a href="<cq:requestURL><cq:removeParam name="language"/></cq:requestURL>">remove filter</a>

7.6.2.2 Sling Tag Library

The Sling tag library contains helpful Sling functions.

When you use the Sling Tag Library in your script, the script must start with the following code:

<%@ taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling/1.0" %>

Note

When the /libs/wcm/global.jsp file is included in the script, the sling taglib isautomatically declared.

7.6.2.2.1 <sling:include>

The <sling:include> tag includes a resource into the current page.

It has the following attributes:

flushA boolean defining whether to flush the output before including the target.

resourceThe resource object to be included in the current request processing. Either resource or pathmust be specified. If both are specified, the resource takes precedence.

pathThe path to the resource object to be included in the current request processing. If this path isrelative it is appended to the path of the current resource whose script is including the givenresource. Either resource or path must be specified. If both are specified, the resource takesprecedence.

resourceTypeThe resource type of the resource to be included. If the resource type is set, the path must bethe exact path to a resource object: in this case, adding parameters, selectors and extensionsto the path is not supported.

Page 63: Cq5 Guide Developer

Components

Page 59 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

If the resource to be included is specified with the path attribute that cannot be resolved to aresource, the tag may create a synthetic resource object out of the path and this resource type.

replaceSelectorsWhen dispatching, the selectors are replaced with the value of this attribute.

addSelectorsWhen dispatching, the value of this attribute is added to the selectors.

replaceSuffixWhen dispatching, the suffix is replaced by the value of this attribute.

Note

The resolution of the resource and the script that are included with the <sling:include> tagis the same as for a normal sling URL resolution. By default, the selectors, extension, etc.from the current request are used for the included script as well. They can be modifiedthrough the tag attributes: for example replaceSelectors="foo.bar" allows you to overwritethe selectors.

Examples:

<div class="item"><sling:include path="<%= pathtoinclude %>"/></div>

<sling:include resource="<%= par %>"/>

<sling:include addSelectors="spool"/>

<sling:include resource="<%= par %>" resourceType="<%= newType %>"/>

<sling:include replaceSelectors="content" />

7.6.2.2.2 <sling:defineObjects>

The <sling:defineObjects> tag exposes the following, regularly used, scripting objects which can bereferenced by the developer:

slingRequestSlingHttpServletRequest object, providing access to the HTTP request header information -extends the standard HttpServletRequest - and provides access to Sling-specific things likeresource, path info, selector, etc.

slingResponseSlingHttpServletResponse object, providing access for the HTTP response that is created bythe server. This is currently the same as the HttpServletResponse from which it extends.

requestThe standard JSP request object which is a pure HttpServletRequest.

responseThe standard JSP response object which is a pure HttpServletResponse.

resourceResolverThe current ResourceResolver object. It is the same as slingRequest.getResourceResolver().

slingA SlingScriptHelper object, containing convenience methods for scripts, mainly sling.include('/some/other/resource') for including the responses of other resources inside this response (eg.embedding header html snippets) and sling.getService(foo.bar.Service.class) to retrieve OSGiservices available in Sling (Class notation depending on scripting language).

Page 64: Cq5 Guide Developer

Components

Page 60 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

resourcethe current Resource object to handle, depending on the URL of the request. It is the same asslingRequest.getResource().

currentNodeIf the current resource points to a JCR node (which is typically the case in Sling), this givesdirect access to the Node object. Otherwise this object is not defined.

logProvides an SLF4J Logger for logging to the Sling log system from within scripts, eg.log.info("Executing my script").

It has the following attributes:

requestName

responseName

resourceName

nodeName

logName

resourceResolverName

slingName

Example:

<%@page session="false" %><%%><%@page import="com.day.cq.wcm.foundation.forms.ValidationHelper"%><%%><%@taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling/1.0" %><%%><sling:defineObjects/>

7.7 A closer look at a few of the foundation components...

The following sections explain how the most commonly used components of the reference websiteGeometrixx have been developed.

7.7.1 Top Navigation Component

The Top Navigation Component displays the top level pages of the website. This navigationcomponent is placed at the top of the content pages in the website.

There is no content to be handled by this component. Therefore there is no need for a dialog, onlyrendering.

Specification summary:

• /libs/foundation/components/topnav

• Displays level one pages (below Homepage).

• Respects On/Off status and uses image rendering.

• Displays as in the following screenshot:

Page 65: Cq5 Guide Developer

Components

Page 61 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

7.7.1.1 Navigation Essentials

The main function of a navigation component is to:

• show the hierarchical page structure of a website

• provide the possibility to access the pages within this structure.

To achieve this, functionality to “get the childpages” of a specific page is essential. Also required isthe functionality to: get the path of the parent page of any page on a specific absolute level (startpage of the navigation), check the validity of a page and of course get the path and title of a page.

The following are an introduction to the relevant functionality (API calls):

• com.day.cq.wcm.core.PageManager.getPage(String path): get the page related to apath

• com.day.cq.wcm.core.Page.listChildren(): get the childpages of the page

• com.day.cq.wcm.core.Page.getPath() + .getTitle(): get the path or title of the pagerespectively

• com.day.cq.wcm.core.Page.isValid() + .isHideInNav(): checks if the page is validor the hide in navigation property is set respectively

• com.day.cq.wcm.core.Page.getAbsoluteParent(int level): Get the the parent pageon an absolute level

• PageFilter(): The default CQ Page filter: checks if the page is valid (by checking that theproperty hideInNav is not set, performing checks on On-/Offtime etc); can be used instead ofisValid() and isHideInNav()

For more detailed information please have a look at the Javadoc provided with CQ5 WCM.

7.7.1.2 Image Rendering Essentials

To be able to use image based navigation items, a mechanism is needed to request a page in an“image navigation item view”.

To achieve this a specific selector is added to the request for the navigation item image of a page;for example, /path/to/a/page.navimage.png. Requests with such a selector have to behandled by an image processing mechanism. Sling's request processing mechanism is used forthis. To realize this, an image processing script (or servlet) is added, this handles all requestswith the specific selector (for example, /contentpage/navimage.png.jsp or /contentpage/navimage.png.java).

For rendering text images the abstract servlet AbstractImageServlet is very helpful. By overwritingthe createLayer() method, it is possible to programmatically create a fully customized image.

The following lists the relevant functionalities (API calls):

• com.day.cq.wcm.commons.AbstractImageServlet

• com.day.cq.wcm.commons.WCMUtils

• com.day.cq.wcm.foundation.ImageHelper

• com.day.image.Font

• com.day.image.Layer

For more detailed information please have a look at the Javadoc provided with CQ5 WCM.

Page 66: Cq5 Guide Developer

Components

Page 62 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

7.7.1.3 Image based Top Navigation Component

The Top Navigation component renders graphical (image based) navigation items.

The images for the navigation items are requested from the page resources in a specific view.This means, the paths of the image tags for the navigation items are equivalent to the paths of thepages that the navigation items represent. To identify the view (kind of presentation) the resource(page) is rendered by, a specific URL selector ('navimage') is added.

7.7.2 List Children Component

The List Children component displays the child pages under a given root page. The root pagecan be configured for every instance of this component (for every paragraph which is renderedby this component). Therefore a dialog is needed to store the path of the root page as content inthe corresponding paragraph resource. If no root page is set, the current page is taken as the rootpage. The component displays a list of links with title, description and date.

Specification summary:

• Display a list of links with title, description and date, referring to pages which are below either thecurrent page or a root page defined by the path provided in a dialog

• /libs/foundation/components/listchildren

• Respects the On/Off status of displayed pages

• The following screenshot shows an example of how it displays:

7.7.2.1 Dialog & Widgets

The Dialog of a component is defined in a subtree of nodes below the component's root node. Theroot node of the dialog is of nodeType cq:Dialog and named dialog. Below this, root nodes for theindividual tabs of the dialog are added. These tab nodes are of nodeType cq:WidgetCollection.Below the tab-nodes, the widget nodes are added; these are of nodeType cq:Widget.

Summary:

Location: /apps/<myapp>/<mycomponent>/dialog

Root Node:

• dialog (cq:Dialog) - node for the dialog

Vital Properties:

• xtype=panel - Defines the dialog's xtype as panel; title sets the title of the dialog

Vital Child Nodes of Dialog Node:

• items (cq:WidgetCollection) - tab nodes within the dialog

Vital Child Nodes of Tab Node:

• <mywidget> (cq:Widget) - widget nodes within the tab

Page 67: Cq5 Guide Developer

Components

Page 63 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Vital Properties:

• name - Defines the name of the property where the content provided by thiswidget is stored (usually something like ./mypropertyname)

• xtype - Defines the widget's xtype

• fieldLabel - The text displayed in the dialog as a label for this widget

7.7.3 Logo Component

The Logo component displays the logo of the website Geometrixx. The logo image and the homelink can be configured globally (same for every page of the website) so that every instance of thiscomponent is identical. Therefore a design dialog is needed to provide the image and path of thehome link to the design of the corresponding Page. The Logo component is placed in the upper leftcorner of all pages on the website.

Specification summary:

• /libs/foundation/components/logo

• Displays a linked logo image in the upper left corner (spooled image, no rendering)

• The path for the link is the path of a page on a defined absolute level

• The logo image and the level are the same for all pages on the website; store the logo imageand level in the design of geometrixx

• Displays as in the following screenshot

7.7.3.1 Designer

The Designer is used to manage the look-and-feel of the global content; including the path to thetool-pages, image of the logo, design values such as text family, size and so on.

Summary:

Location: /etc/designs

Root Node:

• <mydesign> (cq:Page) - Hierarchy node of the design page

Vital Child Nodes:

• jcr:content (cq:PageContent) - Content node for the design

Vital Properties of Child Node jcr:content:

• sling:resourceType = “wcm/designer” - Reference to the designer renderingcomponent

The Designer values can be accessed by the currentStyle object provided in global.jsp.

Design dialogs are structured in the same way as normal dialogs but are named design_dialog.

Page 68: Cq5 Guide Developer

Components

Page 64 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

7.7.4 Paragraph System

The Paragraph System is a key part of a website as it manages a list of paragraphs. It is usedto structure the individual pieces of content on a website. You can create paragraphs inside theParagraph System, move, copy and delete paragraphs and also use a column control to structureyour content in columns.

The Paragraph System provided in CQ5 WCM foundations covers most of the variants needed andcan also be configured by allowing you to select the components to be activated/deactivated withinyour current paragraph system.

7.7.5 Image Component

The Image component displays images in the main paragraph system.

Specification summary:

• /libs/foundation/components/image

• Displays an image in the main paragraph system.

• The image and certain paragraph-related display properties (title, description, size) are stored inthe paragraph resource by a dialog.

• Some global design properties, valid for all paragraphs of this type (minimal size, maximal size),are stored in the design by a design dialog.

• There is the possibility to crop, map etc the image.

7.7.5.1 Widget smartimage

The smartimage widget is an extended widget used to handle the most common aspects of imagehandling in a WCM system. It controls the upload of the image file and stores the reference to themedia library. It also supports the cropping and mapping of images amongst other functions.

The most important properties of the smartimage widget are:

• xtype - The type of widget ('smartimage').

• name - The place to store the image file (binary), usually ./image/file or ./file.

• title - The title displayed in the dialog.

• cropParameter - The place to store the crop coordinates, usually ./image/imageCrop or ./imageCrop.

• ddGroups - Groups in contentfinder from where assets can be dragged to this widget.

• fileNameParameter - Specifies where the name of the image file will be stored, usually ./image/fileName or ./fileName.

• fileReferenceParameter - Location to store the image reference when an image from the medialibrary is used, usually ./image/fileReference or ./fileReference.

• mapParameter - Where to store the map data, usually ./image/imageMap or ./imageMap.

• requestSuffix - The default suffix to be used when browsing for an image with this widget, usually./image.img.png or ./img.png.

• rotateParameter - Where to store the rotation specification, usually ./image/imageRotate or./imageRotate.

Page 69: Cq5 Guide Developer

Components

Page 65 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

• sizeLimit - Maximum size limit, i.e. 100.

• uploadUrl - The path to be used when storing data temporarily, usually /tmp/uploaded_test/*.

7.7.5.2 Contentfinder Essentials

To be able to drag assets from the contentfinder to a component there must be a drop targetconfiguration node called cq_dropTargets below the edit configuration node (cq:editConfig).

Summary:

Location: /apps/<myapp>/components/<mycomponent>/cq:editConfig/cq:dropTargets

Root node:

• cq:dropTargets (cq:DropTargetConfig) - Hierarchy Node of the drop targetconfiguration.

Below this node the following node tree (with vital properties) must be created forthe smartimage:

• image (nt:unstructured) with the following vital properties:

• accept - The media types to be accepted; i.e. image/gif, image/jpeg orimage/png.

• groups - Groups in the contentfinder from where assets can be accepted, i.e.media

• propertyName - Where the reference will be stored; usually ./image/fileReference or ./fileReference

In the case that the image is stored in a separate image node in the content (forexample, as with textimage, when the image is not the only data to be stored forthe resource) the following two nodes must also be created:

• parameters (nt:unstructured) below the image node

• image (nt:unstructured) below the parameters node with the following vitalproperties:

• sling:resourceType - The resource type to be stored in the case that acomplete paragraph has to be created (as when dragging an asset to theparagraphsystem while pressing the Alt button).

7.7.5.3 Image Component Essentials

This section lists the most relevant functionalities (API calls) for the programmatic manipulation ofimages:

• com.day.cq.wcm.foundation.Image

• addCssClass

• loadStyleData

• setSelector

• setSuffix

Page 70: Cq5 Guide Developer

Components

Page 66 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

• draw

• getDescription

• com.day.cq.wcm.api.components.DropTarget

• com.day.cq.wcm.api.components.EditConfig

• com.day.cq.wcm.commons.WCMUtils

For more detailed information please look at the Javadoc provided with CQ5 WCM.

7.7.5.4 Image Rendering Essentials

As for the Top Navigation component, the AbstractImageServlet is used to render the images. Foran introduction to the AbstractImageServlet, see the section called “Image Rendering Essentials”.

As the request to the resource in the 'image view' has to be detected, a specific selector to therequest of the image (i.e. /path/to/the/resource.img.png) needs to be added. Requests with such aselector are handled by the image processing servlet.

7.7.6 Text & Image Component

The Text & Image Component displays text and images in the main paragraphsystem.

Specification summary:

• /libs/foundation/components/textimage

• Displays a text and image in the main paragraphsystem.

• The text and image together with specific paragraph related display properties (title, description,size) are stored in the paragraph resource (dialog).

• There is the possibility to manipulate the image, including cropping and mapping amongst otherfunctions.

• For the image rendering use the servlet created for the image component (to inherit from theimage component set resourceSuperType)

7.7.6.1 Widget richtext

The richtext widget is an extended widget used to handle the most common aspects of texthandling in a WCM system. It stores the text with the formatting information.

The most important properties of the richtext widget are:

• xtype - The type of the widget ('richtext')

• name - Where the text is stored, usually ./text.

• hideLabel - Defines whether the label should be displayed, usually false.

• richFlag (xtype=hidden) with name ./textIsRich, ignoreData=true and value=true - Used to definethat format is rich text format.

7.7.6.2 Text & Image Component Essentials

This section lists the most relevant functionalities (API calls) for the programmatic manipulation oftexts and images:

Page 71: Cq5 Guide Developer

Components

Page 67 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

• com.day.cq.wcm.foundation.TextFormat

• com.day.cq.wcm.api.WCMMode

For more detailed information please have a look at the Javadoc provided with CQ5 WCM.

7.7.7 Search Component

The Search component can be placed in the paragraph system of any page. It searches thecontent of the site for a query provided in the request.

Specification summary:

• /libs/foundation/components/search

• Displays a search form.

• Displays the result of the search for a query provided in the request (if a query was provided).

• Provides a dialog to define some properties

• Search button text

• No results text

• Previous label

• Next label

• Provides pagination

7.7.7.1 Search Essentials

This section lists the most relevant functionalities (API calls) for the programmatic manipulation ofsearches:

• com.day.cq.wcm.foundation.Search - Search Class to be used for almost every aspect ofthe search. The query is expected in a request parameter named 'q'

• getResult - Get the result object

• com.day.cq.wcm.foundation.Search.Result

• getResultPages

• getPreviousPage

• getNextPage

For more detailed information please have a look at the API documentation provided with CQ5WCM.

Page 72: Cq5 Guide Developer

Page 68 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

8 Guidelines for Using Templates andComponents

CQ components and templates form a very powerful toolkit. They can be used by developers toprovide website business users, editors, and administrators with the functionality to adapt theirwebsites to changing business needs (content agility) while retaining the uniform layout of the sites(brand protection).

A typical challenge for a person responsible for a website, or set of websites (for example in abranch office of a global enterprise), is to introduce a new type of content presentation on theirwebsites.

Let us assume there is a need to add a “newslist” page to the websites, which lists extracts fromother articles already published. The page should have the same design and structure as the restof the website.

The recommended way to approach such a challenge would be to:

• Reuse an existing template to create a new type of page. The template roughly defines pagestructure (navigation elements, panels, and so on), which is further fine-tuned by its design(CSS, graphics).

• Use the paragraph system (parsys/iparsys) on the new pages.

• Define access right to the Design mode of the paragraph systems, so that only authorized people(usually the administrator) can change them.

• Define the components allowed in the given paragraph system so that editors can then place therequired components on the page. In our case it could be a “list” component, which can traversea subtree of pages and extract the information according to predefined rules.

• Editors add and configure the allowed components, on the pages they are responsible for, todeliver the requested functionality (information) to the business.

This illustrates how this approach empowers the contributing users and administrators of thewebsite to respond to business needs quickly, without requiring the involvement of developmentteams. Alternative methods, such as creating a new template, is usually a costly exercise, requiringa change management process and involvement of the development team. This makes the wholeprocess much longer and costly.

The developers of CQ based systems should therefore use:

• templates and access control to paragraph system design for uniformity and brand protection

• paragraph system including its configuration options for flexibility.

The following general rules for developers make sense in majority of usual projects:

• Keep the number of templates low - as low as the number of fundamentally different pagestructures on the web sites.

• Provide necessary flexibility and configuration capabilities to your custom components.

• Maximize use of the power and flexibility of CQ paragraph system - the parsys & iparsyscomponents.

Page 73: Cq5 Guide Developer

Page 69 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

9 Java WCM APIThe WCM API package, com.day.cq.wcm.*, is used to access CQ WCM functionality.

Page 74: Cq5 Guide Developer

Page 70 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

10 Multi Site Manager for DevelopersThis document describes:

• What happens in the repository when you set up MSM.

• How MSM can be extended to meet the specific needs of your application.

Please refer to Chapter 1, for instructions on setting up MSM.

10.1 MSM in the Repository

This section describes what happens in the repository when you set up MSM. The first partdescribes the Nodes, Node Types, and Properties that are specific to MSM. The second partdescribes how MSM works at the repository level.

10.1.1 MSM-specific Nodes, Node Types, and Properties

This section describes the Nodes, Node Types, and Properties that are specific to MSM.

10.1.1.1 cq:LiveRelationship mixin

The cq:LiveRelationship mixin is used as a supertype for the cq:LiveSync mixin.

It adds the following properties to the jcr:content node of the Live Copy page:

cq:lastRolledoutdate and time of the last rollout

cq:lastRolledoutByindicates who performed the last rollout

cq:msmSyncStatenot used anymore

10.1.1.2 cq:LiveSync mixin

The cq:LiveSync mixin adds the following nodes and properties to the jcr:content node ofthe Live Copy page:

Page 75: Cq5 Guide Developer

Multi Site Manager for Developers

Page 71 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

• the three properties defined by the cqLiveRelationship mixin, which is the supertype ofcq:LiveSync, which has the following three properties: cq:lastRolledout, cq:lastRolledoutByand cq:msmSyncState.

• the cq:LiveSyncConfig and the cq:LiveSyncAction nodes (see the following description).

10.1.1.3 cq:LiveSyncConfig node and node type

The cq:LiveSyncConfig node is of type cq:LiveSyncConfig and has the three followingproperties storing the configuration of the Live Copy page:

cq:isDeepBoolean defining whether the Live Copy is only for the page (when false) or for the completesub tree (when true). The default value is true. It is not accessible through the Siteadmin ofCQ5.

cq:masterString defining the path of the Blueprint.

cq:triggerString defining the event triggering the synchronization. The default values are rollout,modification, or publish.

Page 76: Cq5 Guide Developer

Multi Site Manager for Developers

Page 72 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

10.1.1.4 cq:LiveSyncAction node and node type

The cq:LiveSyncAction node is of the type cq:LiveSyncAction and defines the synchronizationactions performed on the Live Copy page and on each node of its jcr:content node(paragraphs) when the Blueprint is rolled out.

Each of its child node is an action: its name is the action name and its node type iscq:LiveSyncAction. It must match one action in the client side action set and one serversynchronization action service. The following nodes exist by default:

mandatorythis node has a property called target defining the group that has read-only access to the LiveCopy, for example: surfer.

notifythis node has a property called target defining whether the notification has been enabled (whentrue).

updateContentthis node has a property called status defining whether modifications to the Blueprint will bepropagated (when true).

workflowthis node has a property called target defining the path of the workflow that is started whenthe synchronization actions are triggered, for example: /etc/workflow/models/dam/update_asset.

10.1.1.5 cq:LiveSyncCancelled mixin

When a Live Copy is suspended, the cq:LiveSyncCancelled mixin is added to thejcr:content node of the page or to the paragraph node.

The cq:LiveSyncCancelled mixin adds the boolean property cq:isCancelledForChildren: whentrue, the Live Copy is cancelled for the complete sub tree. This property is not accessible throughthe Siteadmin of CQ5.

Page 77: Cq5 Guide Developer

Multi Site Manager for Developers

Page 73 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

10.1.1.6 cq:BlueprintAction node and node type

The cq:BlueprintAction node is the equivalent of the cq:LiveSyncAction node on theBlueprint side. It defines the synchronization actions performed on the Live Copy page and on eachnode of its jcr:content node (paragraphs) when the Blueprint is rolled out.

Each one of its child node represents an action: its name is the action name and its node typeis cq:LiveSyncAction. It must match one action in the client side action set and one serversynchronization action service. The following nodes exist by default:

mandatorythis node has a property called target defining the group who has a read only access to theLive Copy, for example: surfer.

notifythis node has a property called target defining whether the notification has been enabled (whentrue).

updateContentthis node has a property called status defining whether modifications to the Blueprint will bepropagated (when true).

workflowthis node has a property called target defining the path of the workflow that is started whenthe synchronization actions are triggered, for example: /etc/workflow/models/dam/update_asset.

10.1.2 MSM mechanisms in the repository

When configuring synchronization actions, following mechanisms take place in the repository:

• When a Blueprint is created, a cq:Page node is created under /etc/blueprints.

• When a Live Copy is created, a cq:LiveSyncConfig node and a cq:LiveSyncAction nodeare created under the jcr:content node of the Live Copy root page and only there.

• When a synchronization action is configured on a Blueprint page, a cq:BlueprintActionnode is created under the jcr:content node of the page. For each action acq:LiveSyncAction node is created under the cq:BlueprintAction node.

• When a synchronization action is configured on a Live Copy page, a cq:LiveSyncConfignode and a cq:LiveSyncAction node are created under the jcr:content node of the LiveCopy page.

Page 78: Cq5 Guide Developer

Multi Site Manager for Developers

Page 74 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

• The configuration of a Live Copy page is defined as follows:

• if a cq:LiveSyncConfig node is stored under its jcr:content node, the configuration istaken from this cq:LiveSyncConfig node.

• otherwise, the configuration is inherited from the first parent page with acq:LiveSyncConfig node stored to it.

• The actions to be performed on a Live Copy page are defined according to the following process:

1. In a first step:

• if a cq:LiveSyncAction node is stored under its jcr:content node, the actions aretaken from the cq:LiveSyncAction node.

• otherwise, the actions are inherited from the first parent page with a cq:LiveSyncActionnode stored to it.

2. If for this given Live Copy page, an action is defined on its Blueprint page (it has acq:LiveSyncAction node stored to it):

• if the action does not exist on the Live Copy page, the Blueprint action is added to theaction set and is performed.

• if the action exists on the Live Copy page, the Blueprint action replaces it and is performed.

• When a Live Copy is suspended, the cq:LiveSyncCancelled mixin is added to thejcr:content node of the page or to the paragraph node.

10.2 Extending MSM Functionalities

10.2.1 How to extend synchronization actions

The set of synchronization actions available in the Create Site and Create Live Copydialogs or in the Live Copy and the Blueprint tabs is extensible: custom actions can be addedor complete actions set can be refactored.

CQ.wcm.msm.MSM.ACTIONS is a static JavaScript array that contains client-side configurationfrom the synchronization actions. It is rendered into a CQ.Ext.form.FieldSet.

The code for CQ.wcm.msm.MSM.ACTIONS looks as follows:

CQ.wcm.msm.MSM.ACTIONS = [ CQ.wcm.msm.MSM.UpdateContentAction, CQ.wcm.msm.MSM.NotifyAction, CQ.wcm.msm.MSM.WorkflowAction, CQ.wcm.msm.MSM.MandatoryAction];

CQ.wcm.msm.MSM.UpdateContentAction, CQ.wcm.msm.MSM.NotifyAction,CQ.wcm.msm.MSM.WorkflowAction and CQ.wcm.msm.MSM.MandatoryAction are objectsrepresenting the default configurations for standard synchronization actions.

10.2.1.1 How to change the order of appearance of an action

You can customize the order of the actions by editing the array CQ.wcm.msm.MSM.ACTIONS andreordering the actions within it.

10.2.1.2 How to remove an action

You can remove an action by editing the array CQ.wcm.msm.MSM.ACTIONS and removing anaction from it.

Page 79: Cq5 Guide Developer

Multi Site Manager for Developers

Page 75 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

10.2.1.3 How to create an action

You can create a new action. To do so, two parts have to be configured:

• the JavaScript client side

• the custom synchronization action must be deployed on the server

The following procedure shows you how to add a new synchronization action called "MandatoryStructure": the user selects a user-group that will be able to modify the Live Copy page content butwill not be able to delete or move the page.

10.2.1.3.1 Client side

To add a new synchronization action on the client side, proceed as follows:

1. In CRX Explorer, create a new node under the /apps node. Name = myApp, Type =nt:folder.

2. Create a new node under /apps/myApp: Name = widgets, Type =cq:ClientLibraryFolder. Then:

• edit the property categories and set cq.wcm.edit as Value.

• edit the property dependencies and set cq.widgets as Value.

• add a new property: Name = sling:resourceType, Type = String, Value = widgets/clientlib.

3. Create a new node under /apps/myApp/widgets: Name = source, Type =sling:Folder.

4. Create the js.txt file with the following code and store it under /apps/myApp/widgets(for example with WebDAV):

#base=sourcemyMsmActions.js

Note

To connect to the CRX repository using the WebDAV protocol, check the CRXdocumentation on WebDAV access.

5. Create the myMsmActions.js file with the following code and store it under /apps/myApp/widgets/source (for example with WebDAV):

CQ.wcm.msm.MSM.MandatoryStructureAction = { "xtype": "combo", "fieldLabel": CQ.I18n.getMessage("Mandatory Structure for"), "name": "actionMandatoryStructure", "hiddenName": "msm:actionMandatoryStructure/target", "actionName":"msm:actionMandatoryStructure", "stateful": false, "typeAhead":true, "triggerAction":"all", "inputType":"text", "displayField":"name", "emptyText": "", "minChars":0, "editable":true, "lazyInit": false, "queryParam": "filter",

Page 80: Cq5 Guide Developer

Multi Site Manager for Developers

Page 76 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

"fieldDescription": CQ.I18n.getMessage("Select the groups that will not be able to modify the Live Copy structure."), "tpl" :new CQ.Ext.XTemplate( '<tpl for=".">', '<div class="cq-msm-list cq-msm-mandatory-list">', '<div class="cq-msm-list-entry cq-msm-mandatory-list-entry">{[values.name==""? values.id: values.name]}</div>', '</div>', '</tpl>'), "itemSelector" :"div.cq-msm-mandatory-list", "store": new CQ.Ext.data.Store({ "autoLoad":false, "proxy": new CQ.Ext.data.HttpProxy({ "url": "/bin/security/authorizables.json?limit=25&hideUsers=true", "method":"GET" }), "reader": new CQ.Ext.data.JsonReader({ "root":"authorizables", "totalProperty":"results", "id":"id", "fields":["name","id"]}) }), "defaultValue": ""};

// Adds the new action to the CQ.wcm.msm.MSM.ACTIONS arrayCQ.wcm.msm.MSM.ACTIONS.push(CQ.wcm.msm.MSM.MandatoryStructureAction);

6. The project structure looks as follows in CRX Explorer:

7. In CQ5, open a Live Copy page. In the Page tab of the sidekick, click Page Properties....Select the Live Copy tab to view the newly created widget:

Page 81: Cq5 Guide Developer

Multi Site Manager for Developers

Page 77 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

10.2.1.3.2 Server side

To implement the new action on the Server side, proceed as follows:

Note

Refer to the section called “Installing Eclipse” for installing and setting up Eclipse with aMaven plugin.

1. In Eclipse, create the Core Maven project:

1. In the Menu bar, click File, select New, then Other... .

2. In the dialog, expand the Maven folder, select Maven Project and click Next.

3. Check the Create a simple project box and the Use default Workspacelocations box, then click Next.

4. Define the Maven project:

• Group Id: com.day.cq5.mymsm

• Artifact Id: core

• Name: CQ5 MyMsm Core

• Description: This is the CQ5 MyMsm Core

5. Click Finish.

Page 82: Cq5 Guide Developer

Multi Site Manager for Developers

Page 78 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

2. Set the Java Compiler to version 1.5:

1. Right-click the core project, select Properties.

2. Select Java Compiler and set following properties to 1.5:

• Compiler compliance level

• Generated .class files compatibility

• Source compatibility

3. Click OK.

4. In the dialog window, click Yes.

3. Replace the code in the pom.xml with the following code:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.day.cq5.mymsm</groupId> <artifactId>core</artifactId> <name>CQ5 MyMsm Core</name> <version>0.0.1-SNAPSHOT</version> <description>This is the CQ5 MyMsm Core</description> <packaging>bundle</packaging> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>1.4.3</version> <extensions>true</extensions> <configuration> <instructions> <Export-Package> com.day.cq5.mymsm.*;version=${pom.version} </Export-Package> </instructions> </configuration> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-scr-plugin</artifactId> <version>1.0.8</version> <executions> <execution> <id>generate-scr-scrdescriptor</id> <goals> <goal>scr</goal> </goals> </execution> </executions> </plugin> </plugins>

Page 83: Cq5 Guide Developer

Multi Site Manager for Developers

Page 79 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

</build> <dependencies> <dependency> <groupId>com.day.cq.wcm</groupId> <artifactId>cq-wcm-api</artifactId> <version>5.2.22</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.day.cq</groupId> <artifactId>cq-security</artifactId> <version>5.2.22</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.day.cq</groupId> <artifactId>cq-security-api</artifactId> <version>5.2.6</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.day.crx.sling</groupId> <artifactId>com.day.crx.sling.client</artifactId> <version>1.4.2</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.jcr.api</artifactId> <version>2.0.2-incubator</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.day.cq</groupId> <artifactId>cq-commons</artifactId> <version>5.2.20</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.api</artifactId> <version>2.0.3-incubator-R746167</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>osgi_R4_core</artifactId> <version>1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>osgi_R4_compendium</artifactId> <version>1.0</version> <scope>provided</scope> </dependency> </dependencies> <repositories> <repository>

Page 84: Cq5 Guide Developer

Multi Site Manager for Developers

Page 80 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

<id>day-external-central</id> <name>Day Central Repository</name> <url>http://repo.day.com/archiva/repository/day-central</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>apache-incubating-repository</id> <name>Apache Incubating Repository</name> <url>http://people.apache.org/repo/m2-incubating-repository</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>day-external-central</id> <name>Day Central Repository</name> <url>http://repo.day.com/archiva/repository/day-central</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>apache-incubating-repository</id> <name>Apache Incubating Repository</name> <url>http://people.apache.org/repo/m2-incubating-repository</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </project>

4. Add the credentials into the settings.xml file of your <maven-install-dir>/.m2directory: copy/paste the following code into the <servers></servers> tags:

<server> <id>day-external-central</id> <username>cq5_training</username> <password>tr41n1ng</password> </server>

5. Create the package com.day.cq5.mymsm that will contain the Java classes under core/src/main/java:

1. Under core, right-click src/main/java, select New, then Package.

2. Name it com.day.cq5.mymsm and click Finish.

Page 85: Cq5 Guide Developer

Multi Site Manager for Developers

Page 81 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

6. Create the Java class MandatoryStructureAction:

1. In Eclipse, under core/src/main/java, right-click the com.day.cq5.mymsmpackage, select New, then Class.

2. In the dialog window, name the Java Class MandatoryStructureAction and clickFinish. Eclipse creates and opens the file MandatoryStructureAction.java.

3. In MandatoryStructureAction.java replace the existing code with the following:

package com.day.cq5.mymsm;

import javax.jcr.Node;

import org.apache.sling.api.resource.Resource;import org.apache.sling.api.resource.ResourceResolver;import org.osgi.service.component.ComponentContext;

import com.day.cq.security.util.ActionSet;import com.day.cq.security.util.CRXPolicyManager;import com.day.cq.wcm.api.NameConstants;import com.day.cq.wcm.api.Page;import com.day.cq.wcm.api.PageManager;import com.day.cq.wcm.api.WCMException;import com.day.cq.wcm.api.msm.ActionConfig;import com.day.cq.wcm.api.msm.ActionManager;import com.day.cq.wcm.api.msm.LiveAction;import com.day.cq.wcm.api.msm.LiveRelationship;import com.day.crx.CRXSession;

/** * Set read-ony to group defined in the action config of the relationship (for pages only). Denied ACL are: <ul> * <li>ActionSet.ACTION_NAME_REMOVE</li> * <li>ActionSet.ACTION_NAME_SET_PROPERTY</li> * <li>ActionSet.ACTION_NAME_ACL_MODIFY</li> * </ul> * @scr.component metatype="false" name="com.day.cq5.mymsm.MandatoryStructureAction" immediate="true" * label="%mandatoryaction.name" description="%mandatoryaction.description" * @scr.service interface="com.day.cq.wcm.api.msm.LiveAction" */public class MandatoryStructureAction implements LiveAction { //name of the action in the repository public static final String ACTION_NAME = "mandatoryStructure";

//name of the request parameter used to get/post action properties public static final String ACTION_PARAM_NAME = "msm:actionMandatoryStructure";

public static final int ACTION_RANK = 602; public static final String ACTION_PARAM_TARGET = "target";

//name of the request parameter used to get/post action properties private String[] properties = {MandatoryStructureAction.ACTION_PARAM_TARGET};

/** * @scr.reference */ @SuppressWarnings("UnusedDeclaration") private ActionManager actionManager;

protected void activate(ComponentContext context) { actionManager.registerAcion(this); }

protected void deactivate(ComponentContext context) { actionManager.unregisterAcion(this); }

Page 86: Cq5 Guide Developer

Multi Site Manager for Developers

Page 82 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

public String getName() { return ACTION_NAME; }

public int getRank() { return ACTION_RANK; }

public String[] getPropertiesNames() { return properties; }

public String getParameterName() { return ACTION_PARAM_NAME; }

public void execute(ResourceResolver resolver, LiveRelationship relation, ActionConfig config, boolean autoSave) throws WCMException { try { if (!relation.getStatus().isCancelled() && config != null) { if (config.hasProperty(ACTION_PARAM_TARGET)) { String target = config.getProperty(ACTION_PARAM_TARGET); if (target != null && !target.equals("")) { Resource r = resolver.getResource(relation.getTargetPath()); Node slaveNode = r != null ? r.adaptTo(Node.class): null;//Utils.getNode(resolver, relation.getTargetPath()); if (slaveNode != null) { //set mandatory only on pages if (NameConstants.NN_CONTENT.equals(slaveNode.getName()) && slaveNode.getParent().isNodeType(NameConstants.NT_PAGE)) {

//at this point, action is executed only for a page.

PageManager pm = resolver.adaptTo(PageManager.class); Page p = pm.getContainingPage(resolver.getResource(slaveNode.getPath())); if (p != null) { CRXPolicyManager policyMgr = new CRXPolicyManager((CRXSession) slaveNode.getSession()); policyMgr.enact(p.getPath(), target, false, ActionSet.create(new String[]{ ActionSet.ACTION_NAME_REMOVE, //ActionSet.ACTION_NAME_SET_PROPERTY, //ActionSet.ACTION_NAME_ACL_MODIFY}) ); } } } } } } } catch (Exception re) { throw new WCMException("Error while executing " + getName() + " action", re); } }}

4. Save the changes.

Note

The synchronization action parameter name must match the value returned byLiveAction#getParameterName.

Page 87: Cq5 Guide Developer

Multi Site Manager for Developers

Page 83 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

A synchronization action is an OSGI service that must implement the interfacecom.day.cq.wcm.api.msm.LiveAction and must register itself to the RolloutManager.

As you can see in the above code, a rank has been set to the action (the value ofthe field ACTION_RANK). The actions are executed by following the order of theranks. For the default synchronization actions, the ranks are:

• UpdateContentAction = CUDAction service: 301

• NotifyAction = NotifyAction service: 501

• MandatoryAction = MandatoryAction service: 601

• WorkflowAction = WorkflowAction service: 701

7. Compile the Java class and create the bundle:

1. Right-click the core project, select Run As, then Maven Install.

2. The bundle core-0.0.1-SNAPSHOT.jar (containing the compiled class) is createdunder core/target.

8. In CRX Explorer, create a new node under /apps/myApp. Name = install, Type =nt:folder.

9. Copy the bundle core-0.0.1-SNAPSHOT.jar and store it under /apps/myApp/install(for example with WebDAV).

10. In your browser, in CQ5:

1. Open a Live Copy page. In the Live Copy tab of the Page Properties, select a groupbeside Mandatory Structure for. Click OK.

2. Rollout the corresponding Blueprint page.

3. Log out of CQ5 and log in as a member of the selected group.

4. Refresh the Live Copy page: you can now edit the page but not delete it.

10.2.2 How to define the properties and the nodes that are copied to the LiveCopy

The MSM in CQ5 lets you define:

• which properties are copied by the Update Content synchronization action.

• which node types are part of the rollout process, that is, which synchronization actions areperformed on the node.

To do so:

1. In your browser, open the Apache Felix Web Management Console Configuration(for example: http://localhost:4502/system/console/configMgr).

2. In Configuration, select CQ WCM Rollout Manager.

Page 88: Cq5 Guide Developer

Multi Site Manager for Developers

Page 84 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

3. Configure these two parameters:

Excluded Propertiesjava regexes that define the property names to not copy. If the property name matchesone regex, it will not be copied.

Excluded Nodetypesjava regexes that define the node types to exclude from rollout. If the node type matchesone regex, it will not be included by the rollout manager.

10.2.3 How to remove the "Chapters" step in the "Create Site" wizard

In some cases, the Chapters selection is not required in the Create Site wizard but only theLanguages selection. To remove this step in the default Geometrixx blueprint:

1. In CRX Explorer, remove the node /etc/blueprints/geometrixx/jcr:content/dialog/items/tabs/items/tab_chap.

2. Navigate to /libs/wcm/msm/templates/blueprint/defaults/livecopy_tab/items and create a new node. Name = chapters, Type = cq:Widget.

3. Add following properties to the new node:

• Name = name, Type = String, Value = msm:chapterPages

• Name = value, Type = String, Value = all

• Name = xtype, Type = String, Value = hidden

Page 89: Cq5 Guide Developer

Page 85 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

11 How to Create a Fully FeaturedInternet Website

The tutorial "How to Create a Fully Featured Internet Website" enables you to create a fullyfeatured website with CQ5.

Page 90: Cq5 Guide Developer

Page 86 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

12 DAM Media HandlersCQ5 DAM comes with a set of default workflows and media handlers to process assets. Theworkflow defines the general tasks to be executed on the assets, then delegates the specific tasksto the media handlers, for example thumbnail generation or metadata extraction.

Media handlers are services inside CQ5 DAM that perform specific actions on assets. For example,when an MP3 audio file is uploaded into CQ5, a workflow triggers an MP3 handler that extractsthe metadata and generates a thumbnail. Media handlers are usually used in combination withworkflows. Most common MIME types are supported within CQ5. Specific tasks can be performedon assets by either extending/creating workflows, extending/creating media handlers or disabling/enabling media handlers.

12.1 Default Media Handlers

The following media handlers are available within CQ5 DAM and handle the most common MIMEtypes (click the handler name to access its Javadocs):

Table 12.1.

Handler name Service Name (in theSystem Console)

Supported MIME types

TextHandler com.day.cq.dam.core.impl.handler.TextHandlertext/plain

PdfHandler com.day.cq.dam.handler.standard.pdf.PdfHandlerapplication/pdf

JpegHandler com.day.cq.dam.core.impl.handler.JpegHandlerimage/jpeg

image/jpg

Mp3Handler com.day.cq.dam.handler.standard.mp3.Mp3Handleraudio/mpeg

ZipHandler com.day.cq.dam.handler.standard.zip.ZipHandlerapplication/java-archive

application/zip

PictHandler com.day.cq.dam.handler.standard.pict.PictHandlerimage/pict

StandardImageHandlercom.day.cq.dam.core.impl.handler.StandardImageHandlerimage/gif

image/png

application/photoshop

image/jpeg

image/tiff

image/x-ms-bmp

image/bmp

GenericAssetHandlercom.day.cq.dam.core.impl.handler.GenericAssetHandlerfallback in case no other handler was found toextract data from an asset

All the handlers perform the following tasks:

• extracting all available metadata from the asset.

• creating a thumbnail image out of the asset.

Page 91: Cq5 Guide Developer

DAM Media Handlers

Page 87 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Beside those tasks other MIME type specific tasks are available: refer to the Javadocs for detailedinformation.

It is possible to view the active media handlers:

1. In your browser, navigate to http://<host>:<port>/system/console/components.

2. Click the link com.day.cq.dam.core.impl.store.AssetStoreImpl.

3. A list with all the active media handlers is displayed. For example:

12.2 Using Media Handlers in Workflows to perform tasks onAssets

Media handlers are services that are usually used in combination with workflows.

CQ5 has the following default workflows to process assets:

• DAM Asset Sync and Metadata Extractor

• DAM Delete Asset

• DAM Delete Dam Asset under /content/dam

• DAM Sub Asset Processor

• DAM Update Asset

Existing workflows can be extended and new ones can be created to process assets according tospecific requirements.

By default, when a PDF document is uploaded into the /var/dam/geometrixx/documentsfolder, the default DAM Asset Sync and Metadata Extractor process:

• copies the document into the /content/dam/geometrixx/documents folder

• asks the AssetStore for a handler that is able to process pdf

Then, the pdf handler:

• extracts the metadata

Page 92: Cq5 Guide Developer

DAM Media Handlers

Page 88 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

• generates a thumbnail

• creates sub-assets: each page of the document becomes a sub-asset

The following example shows how to disable the sub-asset creation for PDF documents byextending the workflow: the Process Subassets step will be replaced by an OR-split that checksthe asset filename:

• if it ends with .pdf, the asset reaches the End step.

• if it does not end with .pdf, the asset goes through a Process Subassets step thatgenerates sub-assets.

The workflow will look as follows:

Proceed as follows:

1. Create a service (for example com.day.cq5.myprocess.DoNothingProcess) that doesnot affect the asset and install it in CQ5. This service will be used to bypass the sub-assetcreation step.

Tip

You can refer to the section called “Example: create a specific Text Handler” to seehow to create a service and install it in CQ5.

Page 93: Cq5 Guide Developer

DAM Media Handlers

Page 89 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

2. In your browser, open the Workflow Console (for example: http://localhost:4502/libs/workflow/content/console.html).

3. Select the Models tab and edit the DAM Asset Sync and Metadata Extractorworkflow.

4. Drag and drop an OR Split between the Thumbnail Creation step and the ProcessSubassets step.

5. Click the configuration button of the left step of the OR Split and set the following properties inthe right panel:

• Type: select Process

• Description: This process creates subassets if handler is able toextract subassets

• Handler Advance: true

• Implementation: select com.day.cq.dam.core.process.CreateSubAssetsProcess

• Process Arguments: /etc/workflow/models/dam/sub_asset_processor

• Timeout: Off

• Timeout Handler:

• Title: Process Subassets

6. Click the configuration button of the right step of the OR Split and set the following propertiesin the right panel:

• Type: select Process

• Description: This process does not affect the asset and leads to thenext step

• Handler Advance: true

• Implementation: type the name of the service here (the service created in step 1; forexample: com.day.cq5.myprocess.DoNothingProcess)

• Process Arguments:

• Timeout: Off

• Timeout Handler:

• Title: Do Nothing

7. Delete the Process Subassets step that comes after the end of the OR Split.

8. Create an ecma-script function that is set to true if the filename ends with .pdf, to falseotherwise:

1. In CQDE, create a file under /etc/workflow/scripts and call itmyPdfCheck.ecma.

2. Copy-paste the following code into it:

function check() { if (workflowData.getPayloadType() == "JCR_PATH") { var path = workflowData.getPayload().toString();

Page 94: Cq5 Guide Developer

DAM Media Handlers

Page 90 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

var node = jcrSession.getItem(path); if (node.getPath().indexOf(".pdf") >= 0) { return true; } else { return false; } } else { return false; }}

3. Save the file.

9. Create an ecma-script function that is set to true if the filename does not end with .pdf, tofalse otherwise:

1. In CQDE, create a file under /etc/workflow/scripts and call itmyNotPdfCheck.ecma.

2. Copy-paste the following code into it:

function check() { if (workflowData.getPayloadType() == "JCR_PATH") { var path = workflowData.getPayload().toString(); var node = jcrSession.getItem(path); if (node.getPath().indexOf(".pdf") >= 0) { return false; } else { return true; } } else { return true; }}

3. Save the file.

10. In your browser, set the rule of the Process Subassets step of the OR Split: type /etc/workflow/scripts/myPdfCheck.ecma as value of the Rule.

11. Set the rule of the Do Nothing step of the OR Split: type /etc/workflow/scripts/myNotPdfCheck.ecma as value of the Rule.

12. Save the workflow.

From now on, whenever a pdf file is uploaded into the /var/dam/geometrixx/documentsfolder, the file is copied into /content/dam/geometrixx/documents, its metadata areextracted and thumbnails are generated. Subassets are not created anymore.

12.3 Disabling/Enabling a Media Handler

The media handlers can be disabled or enabled through the Apache Felix Web ManagementConsole. When the media handler is disabled, its tasks are not performed on the assets.

To enable/disable a media handler:

1. In your browser, navigate to http://<host>:<port>/system/console/components.

2. Click the Disable button right beside the name of the media handler. For example:com.day.cq.dam.handler.standard.mp3.Mp3Handler.

3. Refresh the page: a Disabled icon is displayed beside the media handler.

4. To enable the media handler, click the Enable button beside the name of the media handler.

Page 95: Cq5 Guide Developer

DAM Media Handlers

Page 91 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

12.4 Creating a new Media Handler

To support a new media type or to execute specific tasks on an asset, it is necessary to create anew media handler. This section describes how to proceed.

12.4.1 Important Classes and Interfaces

The best way to start an implementation is to inherit from a provided abstract implementationthat takes care of most things and provides reasonable default behaviour: thecom.day.cq.dam.core.AbstractAssetHandler Class.

Note

This class already provides an abstract service descriptor. So if you inherit from this classand use the maven-sling-plugin, make sure that you set the inherit flag to true.

The following methods need to be implemented:

• extractMetadata(): this method extracts all available metadata.

• getThumbnailImage(): this method creates a thumbnail image out of the passed asset.

• getMimeTypes(): this method returns the asset mime type(s).

Here is an example template:

package my.own.stuff;

/** * @scr.component inherit="true" * @scr.service */public class MyMediaHandler extends com.day.cq.dam.core.AbstractAssetHandler {

// implement the relevant parts

}

The interface and classes include:

com.day.cq.dam.api.handler.AssetHandler InterfaceThis interface describes the service which adds support for specific mime types. Adding a newmime type requires to implement this interface. The interface contains methods for importingand exporting the specific documents, for creating thumbnails and extracting metadata.

For more information refer to the Javadocs.

com.day.cq.dam.core.AbstractAssetHandler ClassThis class serves as basis for all other asset handler implementations and provides commonused functionality.

For more information refer to the Javadocs.

com.day.cq.dam.core.AbstractSubAssetHandler Class:This class serves as basis for all other asset handler implementations and provides commonused functionality plus common used functionality for subasset extraction

For more information refer to the Javadocs.

12.4.2 Example: create a specific Text Handler

In this section, you will create a specific Text Handler that generates thumbnails with a watermark.

Proceed as follows:

Page 96: Cq5 Guide Developer

DAM Media Handlers

Page 92 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Note

Refer to the section called “Installing Eclipse” for installing and setting up Eclipse with aMaven plugin and for setting up the dependencies that are needed for the Maven project.

1. In Eclipse, create the myBundle Maven project:

1. In the Menu bar, click File, select New, then Other... .

2. In the dialog, expand the Maven folder, select Maven Project and click Next.

3. Check the Create a simple project box and the Use default Workspacelocations box, then click Next.

4. Define the Maven project:

• Group Id: com.day.cq5.myhandler

• Artifact Id: myBundle

• Name: My CQ5 bundle

• Description: This is my CQ5 bundle

5. Click Finish.

2. Set the Java Compiler to version 1.5:

1. Right-click the myBundle project, select Properties.

2. Select Java Compiler and set following properties to 1.5:

• Compiler compliance level

• Generated .class files compatibility

• Source compatibility

3. Click OK.

4. In the dialog window, click Yes.

3. Replace the code in the pom.xml file with the following code:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- ====================================================================== --> <!-- P A R E N T P R O J E C T D E S C R I P T I O N --> <!-- ====================================================================== --> <parent> <groupId>com.day.cq.dam</groupId> <artifactId>dam</artifactId> <version>5.2.14</version> <relativePath>../parent</relativePath> </parent>

<!-- ====================================================================== --> <!-- P R O J E C T D E S C R I P T I O N --> <!-- ====================================================================== --> <groupId>com.day.cq5.myhandler</groupId> <artifactId>myBundle</artifactId> <name>My CQ5 bundle</name> <version>0.0.1-SNAPSHOT</version> <description>This is my CQ5 bundle</description>

Page 97: Cq5 Guide Developer

DAM Media Handlers

Page 93 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

<packaging>bundle</packaging>

<!-- ====================================================================== --> <!-- B U I L D D E F I N I T I O N --> <!-- ====================================================================== --> <build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-scr-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.sling</groupId> <artifactId>maven-sling-plugin</artifactId> <configuration> <slingUrlSuffix>/libs/dam/install/</slingUrlSuffix> </configuration> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <Bundle-Category>cq5</Bundle-Category> <Export-Package> com.day.cq5.myhandler </Export-Package> </instructions> </configuration> </plugin> </plugins> </build>

<!-- ====================================================================== --> <!-- D E P E N D E N C I E S --> <!-- ====================================================================== --> <dependencies> <dependency> <groupId>com.day.cq.dam</groupId> <artifactId>cq-dam-api</artifactId> <version>5.2.10</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.day.cq.dam</groupId> <artifactId>cq-dam-core</artifactId> <version>5.2.10</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.day.cq</groupId> <artifactId>cq-commons</artifactId> </dependency> <dependency> <groupId>javax.jcr</groupId> <artifactId>jcr</artifactId> </dependency> <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.osgi.compendium</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> </dependency> <dependency> <groupId>commons-collections</groupId>

Page 98: Cq5 Guide Developer

DAM Media Handlers

Page 94 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

<artifactId>commons-collections</artifactId> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> </dependency> <dependency> <groupId>com.day.commons</groupId> <artifactId>day-commons-gfx</artifactId> </dependency> <dependency> <groupId>com.day.commons</groupId> <artifactId>day-commons-text</artifactId> </dependency> <dependency> <groupId>com.day.cq.workflow</groupId> <artifactId>cq-workflow-api</artifactId> </dependency> <dependency> <groupId>com.day.cq.wcm</groupId> <artifactId>cq-wcm-foundation</artifactId> <version>5.2.22</version> </dependency>

</dependencies> </project>

4. Create the package com.day.cq5.myhandler that will contain the Java classes undermyBundle/src/main/java:

1. Under myBundle, right-click src/main/java, select New, then Package.

2. Name it com.day.cq5.myhandler and click Finish.

5. Create the Java class MyHandler:

1. In Eclipse, under myBundle/src/main/java, right-click thecom.day.cq5.myhandler package, select New, then Class.

2. In the dialog window, name the Java Class MyHandler and click Finish. Eclipsecreates and opens the file MyHandler.java.

3. In MyHandler.java replace the existing code with the following:

package com.day.cq5.myhandler;

import java.awt.Color;import java.awt.Rectangle;import java.awt.image.BufferedImage;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;

import javax.jcr.Node;import javax.jcr.RepositoryException;import javax.jcr.Session;

import org.apache.commons.io.IOUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;

import com.day.cq.dam.api.metadata.ExtractedMetadata;import com.day.cq.dam.core.AbstractAssetHandler;import com.day.image.Font;import com.day.image.Layer;import com.day.cq.wcm.foundation.ImageHelper;

/**

Page 99: Cq5 Guide Developer

DAM Media Handlers

Page 95 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

* The <code>MyHandler</code> can extract text files * * @scr.component inherit="true" immediate="true" metatype="false" * @scr.service */

public class MyHandler extends AbstractAssetHandler {

/** * Logger instance for this class. */ private static final Logger log = LoggerFactory.getLogger(MyHandler.class); /** * Music icon margin */ private static final int MARGIN = 10;

/** * @see com.day.cq.dam.api.handler.AssetHandler#getMimeTypes() */ public String[] getMimeTypes() { return new String[] {"text/plain"}; }

public ExtractedMetadata extractMetadata(Node asset) { ExtractedMetadata extractedMetadata = new ExtractedMetadata(); InputStream data = getInputStream(asset); try { // read text data InputStreamReader reader = new InputStreamReader(data); char[] buffer = new char[4096]; String text = "";

while (reader.read(buffer) != -1) { text += new String(buffer); } reader.close(); long wordCount = this.wordCount(text);

extractedMetadata.setProperty("text", text); extractedMetadata.setMetaDataProperty("Word Count",wordCount);

setMimetype(extractedMetadata, asset);

} catch (Throwable t) { log.error("handling error: " + t.toString(), t); } finally { IOUtils.closeQuietly(data); } return extractedMetadata; }

// ----------------------< helpers >---------------------------------------- protected BufferedImage getThumbnailImage(Node node) { ExtractedMetadata metadata = extractMetadata(node); final String text = (String) metadata.getProperty("text"); // create text layer final Layer layer = new Layer(500, 600, Color.WHITE); layer.setPaint(Color.black); Font font = new Font("Arial", 12); String displayText = this.getDisplayText(text, 600, 12); if(displayText!=null && displayText.length() > 0) { // commons-gfx Font class would throw IllegalArgumentException on empty or null text layer.drawText(10, 10, 500, 600, displayText, font, Font.ALIGN_LEFT, 0, 0); } // create watermark and merge with text layer Layer watermarkLayer; try { final Session session = node.getSession();

Page 100: Cq5 Guide Developer

DAM Media Handlers

Page 96 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

watermarkLayer = ImageHelper.createLayer(session, "/var/dam/geometrixx/icons/certificate.png"); watermarkLayer.setX(MARGIN); watermarkLayer.setY(MARGIN); layer.merge(watermarkLayer); } catch (RepositoryException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }

layer.crop(new Rectangle(510, 600)); return layer.getImage(); }

// ---------------< private >----------------------------------------------- /** * This method cuts lines if the text file is too long.. * * @param text * text to check * @param height * text box height (px) * @param fontheight * font height (px) * @return the text which will fit into the box */ private String getDisplayText(String text, int height, int fontheight) { String trimmedText = text.trim(); int numOfLines = height / fontheight; String lines[] = trimmedText.split("\n"); if (lines.length <= numOfLines) { return trimmedText; } else { String cuttetText = ""; for (int i = 0; i < numOfLines; i++) { cuttetText += lines[i] + "\n"; } return cuttetText; } }

/** * This method counts the number of words in a string * * @param text the String whose words would like to be counted * @return the number of words in the string */ private long wordCount(String text) { // We need to keep track of the last character, if we have two white spaces in a row we dont want to double count // The starting of the document is always a whitespace boolean prevWhiteSpace = true; boolean currentWhiteSpace = true; char c; long numwords = 0; int j = text.length(); int i = 0; while (i < j) { c = text.charAt(i++); if (c == 0) { break; } currentWhiteSpace = Character.isWhitespace(c); if (currentWhiteSpace && !prevWhiteSpace) { numwords++; } prevWhiteSpace = currentWhiteSpace;

}

Page 101: Cq5 Guide Developer

DAM Media Handlers

Page 97 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

// If we do not end with a white space then we need to add one extra word if (!currentWhiteSpace) { numwords++; } return numwords; } }

4. Save the changes.

6. Compile the Java class and create the bundle:

1. Right-click the myBundle project, select Run As, then Maven Install.

2. The bundle myBundle-0.0.1-SNAPSHOT.jar (containing the compiled class) iscreated under myBundle/target.

7. In CRX Explorer, create a new node under /apps/myApp. Name = install, Type =nt:folder.

8. Copy the bundle myBundle-0.0.1-SNAPSHOT.jar and store it under /apps/myApp/install (for example with WebDAV).

Note

The new text handler is now active in CQ5.

9. In your browser, open the Apache Felix Web Management Console and disable the defaulttext handler com.day.cq.dam.core.impl.handler.TextHandler.

From now on, whenever you upload a txt file into CQ5 under the /var/dam/documents folder,the file is copied into /content/dam/documents, its metadata are extracted and two thumbnailswith a watermark are generated.

Page 102: Cq5 Guide Developer

Page 98 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

13 Data Modelling13.1 Data Modeling - David Nuescheler's Model

13.1.1 Source

The following details are ideas and comments expressed by David Nuescheler.

David is co-founder and CTO of Day Software AG, a leading provider of global contentmanagement and content infrastructure software. He also leads the development of JSR-170, theJava Content Repository (JCR) application programming interface (API), the technology standardfor content management.

Further updates can also be seen on http://wiki.apache.org/jackrabbit/DavidsModel.

13.1.2 Introduction from David

In various discussions I found that developers are somewhat at unease with the features andfunctionalities presented by JCR when it comes to content modeling. There is no guide and verylittle experience yet on how to model content in a repository and why one content model is betterthan the other.

While in the relational world the software industry has a lot of experience on how to model data, weare still at the early stages for the content repository space.

I would like to start filling this void by expressing my personal opinions on how content shouldbe modeled, hoping that this could some day graduate into something more meaningful to thedevelopers community, which is not just "my opinion" but something that is more generallyapplicable. So consider this my quickly evolving first stab at it.

Important

Disclaimer: These guidelines express my personal, sometimes controversial views. I amlooking forward to debate these guidelines and refine them.

13.1.3 Seven Simple Rules

13.1.3.1 Rule #1: Data First, Structure Later. Maybe.

13.1.3.1.1 Explanation

I recommend not to worry about a declared data structure in an ERD sense. Initially.

Learn to love nt:unstructured (& friends) in development.

I think Stefano pretty much sums this one up.

My bottom-line: Structure is expensive and in many cases it is entirely unnecessary to explicitlydeclare structure to the underlying storage.

There is an implicit contract about structure that your application inherently uses. Let's say I storethe modification date of a blog post in a lastModified property. My App will automatically knowto read the modification date from that same property again, there is really no need to declare thatexplicitly.

Further data constraints like mandatory or type and value constraints should only be applied whererequired for data integrity reasons.

Page 103: Cq5 Guide Developer

Data Modelling

Page 99 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

13.1.3.1.2 Example

The above example of using a "lastModified" Date property on for example "blog post" node, reallydoes not mean that there is a need for a special nodetype. I would definitely use "nt:unstructured"for my blog post nodes at least initially. Since in my blogging application all I am going to do is todisplay the lastModified date anyway (possibly "order by" it) I barely care if it is a Date at all. SinceI implicitly trust my blog-writing application to put a "date" there anyway, there really is no need todeclare the presence of a "lastModified" date in the form a of nodetype.

13.1.3.1.3 Discussion

http://www.nabble.com/DM-Rule-#1:-Data-First,-Structure-Later.-Maybe.-tf4039967.html

13.1.3.2 Rule #2: Drive the content hierarchy, don't let it happen.

13.1.3.2.1 Explanation

The content hierarchy is a very valuable asset. So don't just let it happen, design it. If you don'thave a "good", human-readable name for a node, that's probably that you should reconsider.Arbitrary numbers are hardly ever a "good name".

While it may be extremely easy to quickly put an existing relational model into a hierarchical model,one should put some thought in that process.

In my experience if one thinks of access control and containment usually good drivers for thecontent hierarchy. Think of it as if it was your file system. Maybe even use files and folders tomodel it on your local disk.

Personally I prefer hierarchy conventions over the nodetyping system in a lot of cases initially, andintroduce the typing later.

13.1.3.2.2 Example

I would model a simple blogging system as follows. Please note that initially I don't even care aboutthe respective nodetypes that I use at this point.

/content/myblog/content/myblog/posts/content/myblog/posts/what_i_learned_today/content/myblog/posts/iphone_shipping

/content/myblog/comments/iphone_shipping/i_like_it_too/content/myblog/comments/iphone_shipping/i_like_it_too/i_hate_it

I think one of the things that become apparent is that we all understand the structure of the contentbased on the example without any further explanations.

What may be unexpected initially is why I wouldn't store the "comments" with the "post", which isdue to access control which I would like to be applied in a reasonably hierarchical way.

Using the above content model I can easily allow the "anonymous" user to "create" comments, butkeep the anonymous user on a read-only basis for the rest of the workspace.

13.1.3.2.3 Discussion

http://www.nabble.com/DM-Rule-#2:-Drive-the-content-hierarchy,-don't-let-it-happen.-tf4039994.html

13.1.3.3 Rule #3: Workspaces are for clone(), merge() and update().

13.1.3.3.1 Explanation

If you don't use clone(), merge() or update() methods in your application a single workspace isprobably the way to go.

Page 104: Cq5 Guide Developer

Data Modelling

Page 100 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

"Corresponding nodes" is a concept defined in the JCR spec. Essentially, it boils down to nodesthat represent the same content, in different so-called workspaces.

JCR introduces the very abstract concept of Workspaces which leaves a lot of developers unclearon what to do with them. I would like to propose to put your use of workspaces to the following totest.

If you have a considerable overlap of "corresponding" nodes (essentially the nodes with the sameUUID) in multiple workspaces you probably put workspaces to good use.

If there is no overlap of nodes with the same UUID you are probably abusing workspaces.

Workspaces should not be used for access control. Visibility of content for a particular group ofusers is not a good argument to separate things into different workspaces. JCR features "AccessControl" in the content repository to provide for that.

Workspaces are the boundary for references and query.

13.1.3.3.2 Example

Use workspaces for things like:

• v1.2 of your project vs. a v1.3 of your project

• a "development", "QA" and a "published" state of content

Do not use workspaces for things like:

• user home directories

• distinct content for different target audiences like public, private, local, ...

• mail-inboxes for different users

13.1.3.3.3 Discussion

http://www.nabble.com/DM-Rule-#3:-Workspaces-are-for-corresponding-nodes.-tf4040010.html

13.1.3.4 Rule #4: Beware of Same Name Siblings.

13.1.3.4.1 Explanation

While Same Name Siblings (SNS) have been introduced into the spec to allow compatibility withdata structures that are designed for and expressed through XML and therefore are extremelyvaluable to JCR, SNS come with a substantial overhead and complexity for the repository.

Any path into the content repository that contains an SNS in one of its path segments becomesmuch less stable, if an SNS is removed or reordered, it has an impact on the paths of all the otherSNS and their children.

For import of XML or interaction with existing XML SNS maybe necessary and useful but I havenever used SNS, and never will in my "green field" data models.

13.1.3.4.2 Example

Use

/content/myblog/posts/what_i_learned_today/content/myblog/posts/iphone_shipping

instead of

Page 105: Cq5 Guide Developer

Data Modelling

Page 101 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

/content/blog[1]/post[1]/content/blog[1]/post[2]

13.1.3.4.3 Discussion

http://www.nabble.com/DM-Rule-#4:-Beware-of-Same-Name-Siblings.-tf4040024.html

13.1.3.5 Rule #5: References considered harmful.

13.1.3.5.1 Explanation

References imply referential integrity. I find it important to understand that references do not justadd additional cost for the repository managing the referential integrity, but they also are costlyfrom a content flexibility perspective.

Personally I make sure I only ever use references when I really cannot deal with a danglingreference and otherwise use a path, a name or a string UUID to refer to another node.

13.1.3.5.2 Example

Let's assume I allow "references" from a document (a) to another document (b). If I model thisrelation using reference properties this means that the two documents are linked on a repositorylevel. I cannot export/import document (a) individually, since the reference property's target maynot exist. Other operations like merge, update, restore or clone are affected as well.

So I would either model those references as "weak-references" (in JCR v1.0 this essentially boilsdown to string properties that contain the uuid of the target node) or simply use a path. Sometimesthe path is more meaningful to begin with.

I think there are use cases where a system really can't work if a reference is dangling, but I justcan't come up with a good "real" yet simple example from my direct experience.

13.1.3.5.3 Discussion

http://www.nabble.com/DM-Rule-#5:-References-considered-harmful.-tf4040042.html

13.1.3.6 Rule #6: Files are Files are Files.

13.1.3.6.1 Explanation

If a content model exposes something that even remotely smells like a file or a folder I try to use (orextend from) nt:file, nt:folder and nt:resource.

In my experience a lot of generic applications allow interaction with nt:folder and nt:files implicitlyand know how to handle and display those event if they are enriched with additional meta-information. For example a direct interaction with file server implementations like CIFS or WebDAVsitting on top of JCR become implicit.

I think as good rule of thumb one could use the following: If you need to store the filename andthe mime-type then nt:file/nt:resource is a very good match. If you could have multiple "files" annt:folder is a good place to store them.

If you need to add meta information for your resource, let's say an "author" or a "description"property, extend nt:resource not the nt:file. I rarely extend nt:file and frequently extend nt:resource.

13.1.3.6.2 Example

Let's assume that someone would like to upload an image to a blog entry at:

/content/myblog/posts/iphone_shipping

Page 106: Cq5 Guide Developer

Data Modelling

Page 102 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

and maybe the initial gut reaction would be to add a binary property containing the picture.

While there certainly are good use cases to use just a binary property (let's say the name isirrelevant and the mime-type is implicit) in this case I would recommend the following structure formy blog example.

/content/myblog/posts/iphone_shipping/attachments [nt:folder]/content/myblog/posts/iphone_shipping/attachments/front.jpg [nt:file]/content/myblog/posts/iphone_shipping/attachments/front.jpg/jcr:content [nt:resource]

13.1.3.6.3 Discussion

http://www.nabble.com/DM-Rule-#6:-Files-are-Files-are-Files.-tf4040063.html

13.1.3.7 Rule #7: IDs are evil.

13.1.3.7.1 Explanation

In relational databases IDs are a necessary means to express relations, so people tend to usethem in content models as well. Mostly for the wrong reasons through.

If your content model is full of properties that end in "Id" you probably are not leveraging thehierarchy properly.

It is true that some nodes need a stable identification throughout their live cycle. Much fewer thanyou might think though. mix:referenceable provides such a mechanism built into the repository,so there really is no need to come up with an additional means of identifying a node in a stablefashion.

Keep also in mind that items can be identified by path, and as much as "symlinks" make waymore sense for most users than hardlinks in a unix filesystem, a path makes a sense for mostapplications to refer to a target node.

More importantly, it is **mix**:referenceable which means that it can be applied to a node at thepoint in time when you actually need to reference it.

So let's say just because you would like to be able to potentially reference a node of type"Document" does not mean that your "Document" nodetype has to extend from mix:referenceablein a static fashion since it can be added to any instance of the "Document" dynamically.

13.1.3.7.2 Example

use:

/content/myblog/posts/iphone_shipping/attachments/front.jpg

instead of:

[Blog]- blogId- author

[Post]- postId- blogId- title- text- date

[Attachment]- attachmentId- postId- filename

Page 107: Cq5 Guide Developer

Data Modelling

Page 103 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

+ resource (nt:resource)

13.1.3.7.3 Discussion

http://www.nabble.com/DM-Rule-#7:-IDs-are-evil.-tf4040076.html

Page 108: Cq5 Guide Developer

Page 104 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Appendix A. Keyboard ShortcutsTable A.1. Keyboard Shortcuts

Location Shortcut Description

Page with a teasercomponent.

Ctrl-Alt-c Shows the clickstream cloud: collection of pagetags related to clicks that the user has made andused to focus the teaser.

Content Finder - Searchbox

down-arrow Trigger a suggestions list. Needed when toofew characters have been entered to trigger thelist automatically (this happens when 2 or morecharacters have been entered).

right-arrow

(on a suggested path)

Select item and trigger suggestions for theselected path.

left-arrow

(on a suggested path)

Select item and trigger suggestions for itsancestors (as in siblings of parent).

Enter

(on a suggested path)

Select item and trigger search.

Esc Close suggestions layer.

Drag assets, drop ondestination

Alt+drag The drop action produces a new paragraph;instead of replacing the asset in the destination.

Content Window (EditMode) - Paragraphs

Shift-Click Select multiple paragraphs.

Ctrl-Click Select multiple paragraphs.

Ctrl-C Copy selected paragraph(s).

Ctrl-X Cut selected paragraph(s).

Note: The cut paragraph will not disappear until ithas been pasted to the new location.

Ctrl-V Paste paragraphs from clipboard.

Alt-Ctrl-V Paste as reference.

Del Delete selected paragraph(s).

Backspace Delete selected paragraph(s).

Alt-right-click Force default (browser) context menu.

Table A.2. Extended Keyboard Shortcuts

Location Shortcut Description

Page Ctrl-Shift-U with ?debugClientLibs=trueset in the URL.

To see timing statistics for page loading.

Page 109: Cq5 Guide Developer

Page 105 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Appendix B. Security ChecklistThis section deals with various steps you should take to ensure that your CQ5 installation issecure.

B.1 Use the user session, not the administrative session

This means you should use:

slingRequest.getResourceResolver().adaptTo(Session.class);

B.2 Check for Cross-Site Scripting (XSS)

Cross-site scripting (XSS) allows attackers to inject code into web pages viewed by other users.This security vulnerability can be exploited by malicious web users to bypass access controls.

Warning

CQ5 example code is not protected against such attacks.

Page 110: Cq5 Guide Developer

Page 106 of 106CQ 5.2 WCM

Copyright 1993-2009 Day Management AG

Appendix C. Copyright, Licenses andFormatting Conventions

For all copyright statements and license agreements see Copyright, Licenses and Disclaimers.

C.1 Formatting Conventions

The following tables detail formatting conventions used within this guide:

Table C.1. Formatting Conventions - Text

Style Description Example

Cross-reference Cross-reference to external documents. See the Microsoft Manual ofStyle for Technical Publications.

GUI Item User interface items. Click Save.

Keyboard shortcut Keyboard shortcuts. Press Ctrl+A.

Mouse Button Mouse buttons. Secondary-mouse button(usually the right-mousebutton).

Link Link to anchor-points within the currentdocument and/or external sources.

http://www.day.com

Code Example of programming code. if (weather == sunny) smile;

User Input Example of text, or commands, that youtype.

ls *.xml

<Variable UserInput>

Example of variable text - you type theactual value needed.

ls <cq-installation-dir>

[OptionalParameter]

An optional parameter. ls [<option>] [<filename>]

Computer Output Logging and error messages. ls: cannot accesserror.log:

Table C.2. Formatting Conventions - Actions

When you see this... It means do this...

Ctrl+A Hold down the Ctrl key, then press the A key.

Right-click Press the right-mouse button (or the left-mouse button if your mousehas been configured for left-handed use).

Drag Hold down the left mouse button while moving the item, then release themouse button at the new location (or the right mouse button if your mousehas been configured for left-handed use).