How to Obtaining AEM Page Information in JSON Format

AEM / CQ Page Information in JSON Format


you can get page inform by hitting bellow service by passing page path as parameter

http://server:port/libs/wcm/core/content/pageinfo.json?path=<page-path>

Ex : http://localhost:4502/libs/wcm/core/content/pageinfo.json?path=/content/geometrixx/en






AEM/Adobe CQ : Dialog Editor For Classic UI

Dialog Editor

The dialog editor provides a graphical interface for easily creating and editing dialog boxes and scaffolds. To see how it works, double click on the component's dialog.

In Dilaog Editor you can build you dialog with some cq provided widgets like textfield , pathfield etc...

You may face the following issue

1)  Unable to see dialog after double click on it when any custom widget configured 

For this we have to do overlay html.jsp .

Copy html.jsp form /libs/foundation/components/primary/cq/Dialog/html.jsp to /apps/foundation/components/primary/cq/Dialog/html.jsp

In html.jsp at line number 32  you can see  client libs include to that add your custom widgets client libs 

<cq:includeClientLib categories="cq.widgets,cq.tagging,cq.scaffolding,custom.widgets"/>

2)  Unable to find custom widgets in palette to build dialog

For this you have to  overlay "DialogEditorConstants.js". Copy /libs/cq/ui/widgets/source/widgets/DialogEditorConstants.js to  /apps/cq/ui/widgets/source/widgets/DialogEditorConstants.js. After copy you have to configure your custom widgets / cq widgets.

To Configure follow these steps 

Add your custom/cq provided xtype to CQ.DialogEditor.ALLOWEDCHILDS arra

Eg : Here  I have added dialogfieldset

CQ.DialogEditor.ALLOWEDCHILDS = [ 
            "textfield", 
            "textarea", 
            "numberfield", 
            "selection", 
            "combo", 
            "hidden",
            "richtext",
    "multifield",
    "checkbox",
    "pathfield",
     "dialogfieldset"
];

Add your custom/cq provided xtype configs  to CQ.DialogEditor.MAPPINGS object

add the blow object

dialogfieldset: {
        category:CQ.DialogEditor.CONTAINER,
        text:CQ.I18n.getMessage("Dialogfieldset"),
        insertCfg:{
            "jcr:primaryType":"cq:Widget",
            xtype:"dialogfieldset",
            items:{ "jcr:primaryType":"cq:WidgetCollection" }
        },
allowedChilds: CQ.DialogEditor.ALLOWEDCHILDS,
        propList:{
            title:"Dialogfieldset",
            width:"",
            height:"",
collapsed : false,
collapsible: true,
id : ""
        }
    }


you can add some more properties also if u want. you can see the dialog 'dialogfieldset' under Containers Palette


References 








How to Convert classic UI (based on ExtJS) Dialog Touch-optimized UI (based on Granite UI/CoralUI).

Dialog Conversion Tool

The dialog conversion tool is provided to help you extend existing components that only have a dialog defined for the classic UI (based on ExtJS). The tool uses this original dialog to create a duplicate dialog designed for the touch-optimized UI (based on Granite UI/CoralUI).

The goal of this tool is to automate the upgrade (as far as possible) to increase efficiency and reduce errors.

Click here for more details / Adobe Document 

AEM/Adobe CQ5 : How to Create Dynamic / Static Dropdown For Classic UI Dialog

Xtype : selection  type : select Dialog Snippet

Static Options

<text-align
jcr:primaryType="cq:Widget"
defaultValue="left"
fieldLabel="Text Align"
name="./textAlign"
type="select"
value="left"
xtype="selection">
<options jcr:primaryType="cq:WidgetCollection">
<left
jcr:primaryType="nt:unstructured"
text="Left"
value="left"/>
<right
jcr:primaryType="nt:unstructured"
text="Right"
value="right"/>
<center
jcr:primaryType="nt:unstructured"
text="Center"
value="center"/>
</options>
</text-align>

By Using optionsProvider function

<text-align
jcr:primaryType="cq:Widget"
defaultValue="left"
fieldLabel="Text Align"
name="./textAlign"
type="select"
value="left"
optionsProvider=" use below fuctions"
xtype="selection"/>

static options 

function(path,rec){

var res= {};
var resItems = [];
resItems["text1"] = "value1";
resItems["text2"] = "value2";
return resItems;
}

Dynamic options 

function(path,rec){
var opt = [];
var resPonseData =  CQ.Util.eval(CQ.HTTP.get("serice URL which return JSON"));
var items = resPonseData.results;
for(var indx in items){
var item = {};
var option = items[indx];
if(option && option.constructor != Function ){
item.text = option.description;
item.value = option.name;
opt.push(item);
}
}
return opt;
}

By using options : this can accept Object[]/String

Static Object 

<text-align
jcr:primaryType="cq:Widget"
defaultValue="left"
fieldLabel="Text Align"
name="./textAlign"
type="select"
value="left"
options=" use below Object/String"
xtype="selection"/>

Sample static object/string

 [
    {
        value: "left", 
        text: "Left"
    },
{
        value: "right", 
        text: "Right"
    },
{
        value: "center", 
        text: "Center"
    }
]

You can call jsp which is in your componet which will generate above structre 


<text-align
jcr:primaryType="cq:Widget"
defaultValue="left"
fieldLabel="Text Align"
name="./textAlign"
type="select"
value="left"
options=$PATH.options.json
xtype="selection"/>

Note : options.json.jsp should be under the your dilaog's component

You can Directly call the URL which will return Json , need to configure display value and text attributes in response 

<text-align
jcr:primaryType="cq:Widget"
defaultValue="left"
fieldLabel="Text Align"
name="./textAlign"
type="select"
value="left"
options="service/servlet url which return JSON response . see below for sample response"
optionsRoot="results"
optionsTextField="title"
optionsValueField="name"
xtype="selection"/>

Sample JSON Which is return by service/servlet

{
"results" : [
{"name":"left","title":"Left"},
{"name":"right","title":"Left"},
{"name":"center","title":"Center"}
]
}




Content Compare and Import Tool For Adobe CQ

Content Compare and Import Tool

If you want to compare and import content differences from one CQ instance to another CQ instance. Find the below URL for more details and tool .






reCaptcha / Captcha Integration with Adobe CQ5/AEM6.0

Before going to start you should register with reCAPTCHA to get a public and private key to use in the code.

Loading widget

create a CQ component Ex : captchintegration
Add below code to your component JSP

<%@include file="/libs/foundation/global.jsp"%>
<%@ page import="net.tanesha.recaptcha.ReCaptcha" %>
<%@ page import="net.tanesha.recaptcha.*" %>

<%
  //Getting remote ip addres to validate catpcha 
  String ipAddress = request.getHeader("X-FORWARDED-FOR");  
  if (ipAddress == null) {  
ipAddress = request.getRemoteAddr();  
   } 

 %>
    <input type="hidden" value="<%=ipAddress%>" id="remoteIPAdderess" >
    <input type="hidden" value="<%=currentNode.getPath()%>" id="curNodePath" >
    <% ReCaptcha reCaptcha = ReCaptchaFactory.newReCaptcha("<Public Key>", "<Private Key>", false); %>
    
    <h1 id="page-title" class="title">Google Captch Integration in CQ</h1>
    <form accept-charset="UTF-8" id="testCaptcha" method="post" action="" class="contact-press-form ajax-form">
        <div id="gooleCaptcha">
            <input type="hidden" value="form-U5ArplaaF5MKYCMnyZkQDZfvXEy7bO7JLc5e6VCKses"  name="form_build_id"> 
            <input type="hidden" value="apollocontactpress_contact_form" name="form_id">
    
            <fieldset class="captcha form-wrapper">
                <legend>
                    <span class="fieldset-legend">CAPTCHA</span>
                </legend>
                <div class="fieldset-wrapper form-item form-item-captcha">
                    <%=reCaptcha.createRecaptchaHtml(null, "clean", null) %>
                    <div class="error-message"></div>
                </div>
            </fieldset>
            <input type="button" id="test" class='testCaptcha' value="test">
        </div>
    </form>

<script>

$(function() { 
  
  $('#gooleCaptcha').on('click','.testCaptcha',function(){
      alert("redy captch integration");
      var cpatchaFlag = false;
        var remoteIP=$('#remoteIPAdderess').val();
        var currentNodePath = $("#curNodePath").val();        
        var captchaField = $('#recaptcha_response_field');
        var capResponse=$('#recaptcha_response_field').val();
        var capChallange=$('#recaptcha_challenge_field').val();                 
        var captchValUrl=currentNodePath+'.validatecaptcha.html';
        if($.trim(capResponse).length === 0){
alert("response is empty");
}else{  
            var isValidCaptcha="";
            $.ajax({                          
                url: captchValUrl,
                async: false,
                data: {'remoteAddr':remoteIP,'recaptcha_response_field' : capResponse,'recaptcha_challenge_field':capChallange},
                success: function (response, status, xml) {
                    isValidCaptcha=response;
                }
            });
            
            if($.trim(isValidCaptcha) === 'true'){ 
                alert("valid captcha");
                $('#recaptcha_response_field').css({border : '1px solid black !important'});
            }else{
                alert("invalid captcha");
                $('#recaptcha_response_field').css({border : '1px solid red !important'});
            }
            
        }
  });  
});
    </script>


Validate Captcha 

To validate Captcha create validatecaptcha.jsp under you component. 
Add below code to newly created JSP

<%@include file="/libs/foundation/global.jsp"%>
<%@ page import="net.tanesha.recaptcha.ReCaptcha" %>
<%@ page import="net.tanesha.recaptcha.*" %>
<%
ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
reCaptcha.setPrivateKey("<Private Key>");
String remoteAddr =  request.getParameter("remoteAddr");
String challenge = request.getParameter("recaptcha_challenge_field");
String uresponse = request.getParameter("recaptcha_response_field");
ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(remoteAddr, challenge, uresponse);
if (reCaptchaResponse.isValid()) {
  out.print("true");
  log.info("valid capticha");
} else {
  out.print("false");
  log.info("invalid capticha");
}
%>

Maven dependency 

I have use the below maven dependency and exported in CORE bundle

     <dependency>
  <groupId>net.tanesha.recaptcha4j</groupId>
  <artifactId>recaptcha4j</artifactId>
  <version>0.0.7</version>
    </dependency>

Note : Replace your public key and private key

How to include clientlibs in you component using Sightly AEM/Adobe CQ/AEM6

How to use client libs in Sightly

First you should declare data-sly-use.clientlibInclude in your .html file

<div data-sly-use.clientlibInclude="${'/libs/granite/sightly/templates/clientlib.html'}"></div>

how to  include only CSS of clientlib 

<output data-sly-call="${clientlibInclude.css @ categories='clientlib1,clientlib2'}" data-sly-unwrap/>

how to  include only JS of clientlib 

<output data-sly-call="${clientlibInclude.js @ categories='clientlib1,clientlib2'}" data-sly-unwrap />

how to  include both CSS and JS of clientlib 

<output data-sly-call="${clientlibInclude.all @ categories='clientlib1,clientlib2'}" data-sly-unwrap />


Component not showing in Touch UI / SideKick of Classical UI in AEM / Adobe CQ5 / AEM6

To see component in the Touch UI

If you want to see the component in touch UI components list. The component Should have cq:editConfig node

To See Component in the SideKick in Classic UI

  • The component should have dailog.
  • if component have dialog and not showing in sidekick. Check title of Component it should starts with capital letter.