Creating Custom Page Properties Dialog in CQ

Goal


In this post, we create a custom page properties dialog with fields to store additional page information and display it on the page. A custom page properties dialog is useful when you'd like to add project specific page properties and make use of them in the components added on page. Let us also add a simple listener on a page properties field. Source code available for download

Package Install


First Steps


If you are new to developing applications on CQ, i recommend reading the following posts and develop a sample component before you continue...

1) A Developer Installation
2) Developing a sample CQ Page Component


Create the Panel


1) Assuming you have the following page component created and available in CRX



2) Right click on /apps/samples/components/basictemplate, select "Create Node", enter the following details and click Ok

                        Name: customprops
                        Type: cq:TabPanel

3) Add other necessary details for creating the tab panel

                         xtype: tabpanel
                         title: Custom Properties
                         activeTab: 0

4) Save changes in CRX

5) Right click on /apps/samples/components/basictemplate/customprops, select "Create Node", enter the following details and click "Ok"

                    Name: items
                    Type: cq:WidgetCollection

6) Save Changes

7) Follow the same process to create node with name details of type cq:Widget ( /apps/samples/components/basictemplate/customprops/items/details ) with the following details

                xtype: panel
                title: Details

8) Create node items of type cq:WidgetCollection (/apps/samples/components/basictemplate/customprops/items/details/items)

9) Create node message of type cq:Widget (/apps/samples/components/basictemplate/customprops/items/details/items/message), enter the following details and Save changes

                  xtype: textfield
                  fieldLabel: Welcome Message
                  name: ./title
                  defaultValue: Welcome to CQ



10) At this point we've created a Custom Properties dialog Tab Panel with a Text Field to enter some text

Add Panel to SideKick


1) To add the panel to sidekick, Create a file head.jsp ( Right click on /apps/samples/components/basictemplate, Select "Create" -> "Create File" ), Save changes.

2) Checkout the file head.jsp to your IDE. ( I use Intelij IDEA IDE, See this post on how to integrate your IDEA with CRX )

3) Add the following code in your basictemplate head.jsp created above ( These are pieces from /libs/foundation/components/page/head.jsp, /libs/wcm/core/components/init/init.jsp to load the side kick, /libs/foundation/components/page being the sling:resourceSuperType of our basictemplate component )

<%@include file="/libs/foundation/global.jsp"%>
<%@page import="com.day.cq.wcm.api.WCMMode,
                com.day.cq.widget.HtmlLibraryManager,org.apache.commons.lang.StringEscapeUtils"
%>
<%@taglib prefix="cq" uri="http://www.day.com/taglibs/cq/1.0"%>



<head>
    
    <%
        if ( WCMMode.fromRequest(request) != WCMMode.DISABLED ) {
            HtmlLibraryManager htmlMgr = sling.getService(HtmlLibraryManager.class);

            if (htmlMgr != null) {
                htmlMgr.writeCssInclude(slingRequest, out, "cq.wcm.edit", "cq.tagging", "cq.security");
                htmlMgr.writeJsInclude(slingRequest, out, "cq.wcm.edit", "cq.tagging", "cq.security" );
            }

            String dlgPath = null;

            if ( ( editContext != null ) && ( editContext.getComponent() != null ) ) {
                dlgPath = editContext.getComponent().getDialogPath();
            }
    %>

    

    <%
        }
    %>

    <%= StringEscapeUtils.escapeXml(currentPage.getTitle()) %>
</head>

4) Check-in the file to CRX ( or instead of using IDE you can use CRXDE Lite in browser, open head.jsp, add the above code and save changes)

5) Assuming you have created page "My Page" of type "basictemplate" under http://localhost:4502/siteadmin#/content -> FirstApp Demo Site; Access the url http://localhost:4502/cf#/content/firstapp-demo-site/my-page.html, goto SideKick -> Page tab, at the bottom you should see Custom Page Properties. Click and the tab panel we added earlier is displayed in a window



6) Enter "Thank you" in the text field and click ok; the page gets refreshed

7) Open CRXDE Lite (http://localhost:4502/crx/de) and goto /content/firstapp-demo-site/my-page/jcr:content; the title textfield message you added above should have been saved as the property title




8) Let us modify the basictemplate body.jsp (/apps/samples/components/basictemplate/body.jsp) to show this title on the page. Add the following code to body.jsp and check-in to CRX

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

<cq:defineobjects/>

<%
    //properties is an implicit object defined in cq taglib and made available
    //with tag declaration <cq:defineobjects/>
    String myTitle = String.valueOf(properties.get("title"));
    pageContext.setAttribute("myTitle", myTitle);
%>

${myTitle} message was added in SideKick -> Page tab -> Custom Page Properties

9) The "Thank you" message added earlier in "Custom Page Properties" is shown




Add ExtJS Listener on Panel


1) Let's add a sample JS listener on the panel 

2) Open CRXDE Lite, goto /apps/samples/components/basictemplate/customprops, right click and add node listeners of type nt:unstructured. Add the following details

                    afterrender: function(dialog){ myTitleFn(dialog); }



Here we are adding a listener for the afterrender event on tab panel and listener function calls the function myTitleFn with dialog as argument. In the next step we are going define the function "myTitleFn"

3) Define the myTitleFn global function in your basictemplate body.jsp. It's not a best practice to define global functions, always scope the functions in JS objects. We are doing it to keep things simple, the function shows an alert with dialog title.

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

<cq:defineObjects/>

<%
    //properties is an implicit object defined in cq taglib and made available
    //with tag declaration <cq:defineObjects/>
    String myTitle = String.valueOf(properties.get("title"));
    pageContext.setAttribute("myTitle", myTitle);
%>

${myTitle} message was added in SideKick -> Page tab -> Custom Page Properties

<script type="text/javascript">
    var myTitleFn = function(dialog){
        alert("Please enter your welcome message in '" + dialog.title + "'");
    }
</script>

4) Check-in or Save body.jsp in CRX, access page http://localhost:4502/cf#/content/firstapp-demo-site/my-page.html, Click on SideKick -> Page tab -> Custom Page Properties and you should see the alert




 5) Download the source code

7 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Hi, Thanks for sharing this.

    I tried to implement this, but got the error below while loading the page

    TypeError: dom is undefined
    style = dom.style,

    Any idea what that could be?

    Thanks

    ReplyDelete
    Replies
    1. Got a similar error too. Any fix u found?

      Delete
  3. Is there any resources that lists out all the possible properties a node can have?

    ReplyDelete
    Replies
    1. https://docs.adobe.com/docs/en/cq/5-6/widgets-api/index.html

      Delete
  4. One of the biggest challenges that organizations face today is having inaccurate data and being unresponsive to the needs of the Adobe CQ5 CMS Email List organization.

    ReplyDelete