Posts tagged "component dialog"

November 27, 2013

Static multi-image component with image preview

I recently got a requirement in which I had to build a component in which the user can Drag and Drop 2 main images (e.g.: hero) and 3 sub images ( icons,buttons,logos etc). The main requirement was being able to preview these images while the author is creating content for that page.

I got it working after few trials and I am sharing the same.

Environment: CQ561

1. Create a single image component extending the OOTB (xtype=’html5smartimage’) image component. This should be fairly simple and if you need any information on this leave a comment and I can help.

Screen Shot 2013-11-27 at 4.37.12 PM

 

2. Now create another tab in your component structure by copy/pasting your current working image cq:Panel. For E.g.: in my case I copied /apps/blog/components/content/hero/dialog/items/items/imagetab1 and pasted it under /apps/blog/components/content/hero/dialog/items/items/ to create /apps/blog/components/content/hero/dialog/items/items/imagetab2

Screen Shot 2013-11-27 at 4.42.23 PM

 

3. Next to avoid confusion I also renamed the image cq:Widget at /apps/blog/components/content/hero/dialog/items/items/imagetab2/items/image to /apps/blog/components/content/hero/dialog/items/items/imagetab2/items/image4

Screen Shot 2013-11-27 at 4.44.59 PM

 

4. Now we will have to update the properties under image4 cq:Widget (/apps/blog/components/content/hero/dialog/items/items/imagetab2/items/image4) to make this work.

 

table { }td { padding-top: 1px; padding-right: 1px; padding-left: 1px; color: black; font-size: 12pt; font-weight: 400; font-style: normal; text-decoration: none; font-family: Calibri,sans-serif; vertical-align: bottom; border: medium none; white-space: nowrap; }

Property Name New Value
cropParameter ./image4/imagecrop
fileNameParameter ./image4/fileName
fileReferenceParameter ./image4/fielReference
name ./image4/image4file
rotateParameter ./image4/imageRotate

Screen Shot 2013-11-27 at 5.12.56 PM

 

5. Now when you go back to your content page you should have 2 different tabs and both having the image drag and drop functionality. You can extend this concept for more images as long as you make sure the properties are updated correctly for the image cq:Widget.

Screen Shot 2013-11-27 at 5.19.22 PM                                            Screen Shot 2013-11-27 at 5.19.11 PM

6:28 PM Permalink
August 19, 2012

How to integrate with other web services without creating OSGi packages

A lot of enterprise grade systems require some sort of integration with other services these days, to extend and bring in more features into the systems. In this blog post I would like to show a quick and easy way to integrate CQ5 with other web services. Examples below will be showing a RESTful webservice but other webservices like SOAP will take similar approach.

Webservices integration usually involves building a integration layer. A Java Servlet would definitely be a good candidate. But to avoid building / compiling / packaging / deploying such code into an OSGi container, one can easily write a JSP (on the fly) in CQ to handle the integration.

Create an integration layer page:

This integration page is basically to create an instance of a CQ Page so that the rest of the content pages can communicate to it (Things under /app are not exposed or cannot be called directly). And extra benefit about this CQ Page -> You can control who has access to it!

Note the above page is using “Demo – API Page Template”, and here is the mapping:

 

And apipage.jsp is nothing more than what you want to surface in a typical Servlet.  Here is snippet of the code:

if (request.getParameter("action") != null) {
    if (request.getParameter("action").equals("getSomething")) {
        Node demoNode = resourceResolver.getResource(INTEGRATION_DESIGN_NODEPATH).adaptTo(Node.class);
        response.setContentType("application/json");
        out.write(getSomething(demoNode));
 
    } else if (request.getParameter("action").equals("getCategories")) {
        Node demoNode = resourceResolver.getResource(INTEGRATION_DESIGN_NODEPATH).adaptTo(Node.class);
        response.setContentType("application/json");
        out.write(getCategories(demoNode));
 
    } else if (request.getParameter("action").equals("getFields") &&
            request.getParameter("param1") != null &&
            request.getParameter("param2") != null) {
        response.setContentType("application/json");
        out.write(getFields(
            request.getParameter("param1"),
            request.getParameter("param2"));
 
    } else {
        response.setContentType("application/json");
        out.write("{\"error\":\"error\"}");
    }
}

 

And derived from the above, we now have the following links to retrieve data:

http://_server_:_port_/content/integrationdemo/en/integration/integrationapi?action=getSomething

http://_server_:_port_/content/integrationdemo/en/integration/integrationapi?action=getCategories

http://_server_:_port_/content/integrationdemo/en/integration/integrationapi?action=getFields&param1=test&param2=data

 

The integration implementation will be per your requirements, but at a high level you can pretty much do everything-in-a-servlet inside a JSP. JSPs are Servlets after all. Here is a snippet of a http call (to a webservice) inside the same JSP:

 

static String getFields(String apiKey, String accessToken, String someJson) {
    HttpClient httpClient = new HttpClient();
    HttpClientParams httpClientParams = new HttpClientParams();
    DefaultHttpMethodRetryHandler defaultHttpMethodRetryHandler = new DefaultHttpMethodRetryHandler(0, false);
    httpClientParams.setParameter(HttpClientParams.RETRY_HANDLER, defaultHttpMethodRetryHandler);
    httpClient.setParams(httpClientParams);
 
    PostMethod post = new PostMethod(EXTERNAL_WEBSERVICE_API_URL+apiKey.trim()+"/URL_EXAMPLE/test?oauth_token="+accessToken.trim());
    post.addRequestHeader("Accept", "application/json");
    post.addRequestHeader("Content-Type", "application/json");
    post.setRequestBody(someJson);
 
    try {
        httpClient.executeMethod(post);
        String result = post.getResponseBodyAsString();
 
        if (result != null && !result.equals("")) {
            JSONObject returnObj = new JSONObject(result);
            return returnObj.toString();
        } else {
            return "";
        }
    } catch (Exception ex) {
        return ex.getMessage();
    }   
}

 

And finally, as an option (if you want to integration the CQ authoring experience with an external webservice), you can expose the data retrieved inside a CQ Component dialog field, you will need to configure the widget to retrieve webservice data. Details are documented in:

http://dev.day.com/docs/en/cq/current/widgets-api/index.html?class=CQ.form.Selection

Here’s a quick example:

And the result:

 

Enjoy~

11:21 AM Permalink