Monday, December 19, 2016


Introduction

Content Management systems manage and deliver electronic content to a target audience.The content may be web information, marketing campaigns or social media content. Applications often call third-party http-based RESTful APIs, including social networks, cloud providers, e-commerce and news aggregators.Within larger enterprise environments, applications call multiple internal applications.

There are two ways to call third-party http-based APIs from an AEM application.The first approach is calling directly from client-side and the second approach, using AEM servlet data calls.Here, we are going to discuss the first approach which is calling directly from the client-side.AngularJS calls the third-party API, directly and all logic is on the client-side, instead of on the server-side.

Example

To make this post more interesting, I will be using the OMDb API - a free web service to obtain movie information for our movie search component. This component will be built using Bootstrap for styling and AngularJS, which will retrieve any movie information which we will enter in a search text box.

Develop Movie Search Component

After creating the basic folder structure for our app, we need to create template under /apps/angular/templates/. Then create our movie search component under /apps/angular/components/page.

So as of now, we had created the basic project structure, now we will include AngularJS in our application.

Create a folder with primaryType="cq:ClientLibraryFolder" under /apps/angular/compoents/moviesearchcomponent/ with name clientlibs and include AngularJS. As we already have Angularjs defined in libs, so we just need to add these properties to include Angularjs framework in our application.Along with this we also have to include Bootstrap css and js files to style our component.





Creating the Controller

Now, we will look at app.js which is very important for angularjs application in which we will create a controller can use it to make calls to the OMDB API.Here's a controller named MovieInfoController that will be used for data retrieval and manipulation. Once data is returned from the API the $scope is updated which will drive the user interface.
'use strict';

angular.module('myApp', [])
    .controller('MovieInfoController', function($scope, $http) {
        $scope.$watch('search', function() {
            fetch();
        });
  $scope.search = "Game of Thrones";
  function fetch() {
            $http.get("http://www.omdbapi.com/?t=" + $scope.search + "&plot=full")
                .then(function(response) {
                    $scope.records= response.data;
                });
        }
        $scope.select = function() {
            this.setSelectionRange(0, this.value.length);
        }
});
Explanation 


Here we can see how to inject dependencies like that variable $scope & $http which are passed as a parameter to the function of the controller, $scope is used for sharing values between the view and the controller.This means we are declaring dependencies on both the scope object and the http service.

The search model(search text box value) is undefined when on page loads, so we set it to some content value(Ex: "Game of thrones") and call fetch function, which will call the remote API and ensure that the view is initialized.

Now we will see the MovieInfoController, we set up monitoring of the search model and load the results when the value in the search box changes.As we used the ngModelOptions directive with a debounce value of 500, the result should only be fetched after the user has stopped typing for 500 ms.

Now comes the fetch function.We use Angular's $http.get a function to make the requests, passing query string along with API URL.

We used records model to store the responses on success. Finally, When the user clicks in the text input search button, we have a select function to ensures that the entire text is selected.

Creating the View

Lets now we look our moviesearch component view(moviesearch.html). First thing we need to include required client libs in our page by using Sightly include. Then inside body, we declare our module name as myapp by using angularjs directive ng-app and controller as ng-controller = "MovieInfoController". By using ng-model to bind the input field where user will enter the movie name to the search model(which we declared in our controller).

The main-info div will be used to display information about the searched movie. Here, we start with ng-if directive to show the message "Loading Results....". When the results were returned and assigned that response to records. So records has all required data to display in page.

Here, a complete code of movie search html.
<html>

<head>
    <title>Movie Search !!!</title>
    <sly data-sly-call="${clientLib.all @ categories='cq.widgets'}" data-sly-unwrap="" data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html"></sly>
</head>

<body>
    <div class="container-fluid outerdiv bg-info" ng-app="myApp" ng-controller="MovieInfoController">
     <div class="input-group search-bar">
        <input autofocus="" class="form-control" ng-model-options="{ debounce: 500 }" ng-model="search" onclick="select()" placeholder="Enter movie name" type="text" />
        <span class="input-group-addon bar-style"><i class="glyphicon glyphicon-search"></i></span>
     </div>
<div class="col-md-12" id="main-info">
        <div ng-if="!records">
          Loading results...
        </div>
<div ng-if="records.Response==='True'">
          <img class="img-thumbnail animated flip movie-poster" ng-src="{{ records.Poster=='N/A' ?  'http://placehold.it/150x220&text=N/A' : records.Poster }}" />
          <span class="span-outer">
             <a href="https://www.blogger.com/null">{{ records.Title }}</a>
          </span>
         <strong>Released on:</strong> {{ records.Released }} ({{ records.Runtime }}) &lt/br>
         {{ details.Plot }}
         <div class="outer-p">
             <div class="inner-p">
               <span class="label label-primary">Directors :</span> {{ records.Director }}
             </div>
<div class="inner-p">
               <span class="label label-primary">Actors :</span> {{ records.Actors }}
             </div>
<div class="inner-p">
               <span class="label label-primary">Genre :</span> {{ records.Genre }}
            </div>
</div>
<div class="outer-p-2">
              Ratings:
              <br>
              <strong<IMDb Rating</strong>: <span class="label label-success">{{ records.imdbRating }}</span>
          </div>
</div>
<div ng-if="records.Response==='False'">
          No results found.
        </div>
</div>
</div>
</body>

</html>

Create the web page and drag and drop this component to view the result.



Friday, March 4, 2016


Available Block Statements in Sightly :
Sightly Block statements are custom data attributes added directly to existing HTML element and converting it to a functional dynamic template without breaking the quality of the HTML code.

To know more about useful tools and plugins to learn Sightly , read its previous article
Sightly Beautiful Markup

1.Use - data-sly-use :
It is used to initialize a helper object (defined in Javascript or Java class) and exposes it through a identifier.
Examples for data-sly-use :
We define a component ,sample , located at
/apps/my-project/components/sample
Javascript Logic
It contains JS logic file and sightly component html file located at
/apps/my-project/components/sample/sample.js
/apps/my-project/components/sample/sample.html

use(function(){
      return{
         text:"Hello Sightly"
         };
    });


${sample.text}
Hello Sightly
Java Class Logic
It contains Java file located at
/apps/my-project/components/sample/sample.java
/apps/my-project/components/sample/sample.html


package apps.my_project.components.sample;
  
import com.adobe.cq.sightly.WCMUse;
  
public class Sample extends WCMUse {
    private String text;
      
    @Override
    public void activate() throws Exception {
        text="Hello Sightly";
    }
  
    public String getText() {
        return text;
    }
  
}


${sample.text}
Hello Sightly
Initialize a Java class, where that class is installed as part of an OSGi bundle then its fully-qualified class name must be used:
<div data-sly-use.sample="com.myproject.Sample">${sample.text}</div>

Parameters can be passed to the Use-API by using expresion options :


Scope of the data-sly-use identifier(here sample) is used anywhere after its declaration

${sample.text}
${sample.text}
Hello Sightly
Hello Sightly
The Use statement can also be used to load external templates. We can see this briefly in data-sly-templates.

2. Text - data-sly-text
        i.It is used to replaces the content of its host element with the specified text
        ii.Its element(Ex :  <div></div>) is always shown.
        iii.Its element's content(Ex: <div>This is element's content</div>) is replaced with its evaluated result and there is no identifier.
        iv.The content of the data-sly-text attribute is automatically XSS-protected with the text context.
Example :
sample.html : <div data-sly-text=${currentPage.title}>This is sample content</div>
output : <div>Available Block Statements</div><!--/* It replaces content with currentpage title */-->
And it is not treated specially if it has false or empty variables like
<p data-sly-text="${''}"></p>    <!--/* outputs: */--> <p></p>
<p data-sly-text="${[]}"></p>    <!--/* outputs: */--> <p></p>
<p data-sly-text="${0}"></p>     <!--/* outputs: */--> <p>0</p>
<p data-sly-text="${false}"></p> <!--/* outputs: */--> <p>false</p>

3. Element - data-sly-element
       i.It is used to replaces the element's tag name 
      ii.Always shown Content of the host element but replaced element's tag name
     iii.To consider safety reasons, data-sly-element accepts only the below element names:
a abbr address article aside b bdi bdo blockquote br caption cite code col colgroup
data dd del dfn div dl dt em figcaption figure footer h1 h2 h3 h4 h5 h6 header i ins
kbd li main mark nav ol p pre q rp rt ruby s samp section small span strong sub
sup table tbody td tfoot th thead time tr u var wbr
     iv.If we need to set for other elements then XSS security must be turned off(@context='unsafe').
  Example :

<div data-sly-element="h1">This is Content</div> <!--/* outputs: */--> <h1>This is content</h1>

4.Unwrap - data-sly-unwrap:
   i.It is used to hide its HTML element and show only its content.
  ii.If we need HTML elements only on Sightly presentation logic but doesn't need to display in output then we would use this block statement.

Example :
ExamTem.html

${title}

Templates supports Recursion : ExamRec.html
  • "${item.title}"
To know more about Template & calls, click AdobeAEMClub

Sunday, February 28, 2016


Sightly means "pleasing to the sight" ,so  it means to make the website pages more attractive with minimal effort. Sightly is introduced to replace JSP & ESP from AEM 6.0 and it is a new HTML template language. Sightly plays a very important role to define the output sent to the browser by specifying HTML itself with some basic presentation and variables to be evaluated at runtime.
In this article , the below topics on Sightly are explained
  •     Features of Sightly
  •     Sightly developing tools
  •     Block Statements in Sightly

Features of Sightly
     1. Light weight - No dependencies , fast and lean
     2. Secure - Automatic contextual XSS protection and URL externalization
     3. Code-less - Enforce separation of concerns between logic and markup
     4. Powerful - Straight-forward API for logic, allowing to do virtually anything
     5. Intuitive - Clear, simple & restricted feature set

Tools & Plugins
      1. Sightly Read Eval Print Loop(REPL) - Great tool to learn Sightly which is a live code editing environment. Click here to learn more.
      2. AEM Developer tools for Eclipse - It is Eclipse plugin used to develop Sightly projects more easily. Click here to learn more.
      3. AEM Brackets Extension - It provides an easy way to edit AEM components and Client Libraries and front-end developers can easily work with minimal AEM knowledge in projects.Click here to learn more.

Block Statements in Sightly
Block plugins in Sightly are defined by data-sly-* attributes set on HTML elements. 
All HTML elements can have a closing tag or self-closing like
<tag data-sly-BLOCK></tag>                                 
<!--/* A block is simply consists in a data-sly attribute set on an element. */-->

<tag data-sly-BLOCK/>                                      
<!--/* Empty elements (without a closing tag) should have the trailing slash. */-->
Attributes can have a value such as String , expressions or boolean
<tag data-sly-BLOCK="string value"/>                       
<!--/* A block statement usually has a value passed, but not necessarily. */-->

<tag data-sly-BLOCK="${expression}"/>                      
<!--/* The passed value can be an expression as well. */-->

<tag data-sly-BLOCK="${@ ArgVal='Sightly'}"/>                   
<!--/* Or a parametric expression with arguments. */-->

<tag data-sly-BLOCKONE="value" data-sly-BLOCKTWO="value"/> 
<!--/* Several block statements can be set on a same element. */-->
All evaluated data-sly-* attributes are removed from the generated markup.

Identifiers - data-sly-Block statements
Format : <tag data-sly-Block.identifier="value"></tag>
Examples :
<div data-sly-use.navigation="com.adobe.sightlyExample.MyNavigation">${navigation.title}         </div>
<!--/* MyNavigation is a java class and assigning it to navigation identifier */-->

<div data-sly-test.isEditMode="${wcmmode.edit}">${isEditMode}</div>
<!--/* wcmmode.edit expression's result is assigned to isEditMode identifier */-->

<div data-sly-list.child="${currentPage.listChildren}">${child.properties.jcr:title}</div>
<!--/* currentPage's child page items are assigned to child identifier */-->

<div data-sly-template.nav>Hello World</div>
<div data-sly-call="${nav}"></div>

<!--/* The attribute statement uses the identifier to know to which attribute it should apply it's value: */-->
<div data-sly-attribute.title="${properties.jcr:title}"></div> <!--/* This will create a title attribute */-->

So in next articles I will explain available data-sly-Block statements in Sightly like :
    • data-sly-test                      data-sly-text                       data-sly-use 
    • data-sly-attribute              data-sly-element                 data-sly-list 
    • data-sly-repeat                  data-sly-include                 data-sly-resource 
    • data-sly-template              data-sly-call                       data-sly-unwrap

Monday, February 1, 2016

Consuming Restful Webservice in AEM


In this article , I am going to write about how to consume data from a third-party Restful Webservice in Adobe Experience Manager. I am fetching live cricket score from  Cricinfo using their XML data with the help of org.apache.http package.
Steps to consume Restful web service - 
1.Create and Setup Maven project 
2.Create and compile Java classes that performs the Restful request. 
3.Build and deploy OSGi bundle to Adobe CQ
4.Create template and component to display web service response in webpage.

Create and Setup Maven Project

By performing below steps we can create an Adobe CQ archetype project
   i.Open cmd prompt and go to working project folder
  ii.Execute Maven script to create project folders

mvn archetype:generate -DarchetypeRepository=http://repo.adobe.com/nexus/content/groups/public/ -DarchetypeGroupId=com.day.jcr.vault -DarchetypeArtifactId=multimodule-content-package-archetype -DarchetypeVersion=1.0.2 -DgroupId=my-group-id -DartifactId=myproject -Dversion=1.0-SNAPSHOT -Dpackage=com.mycompany.myproject -DappsFolderName=myproject -DartifactName="My Project" -DcqVersion="5.6.1" -DpackageGroup="My Company"

mvn eclipse:eclipse
iii.After executing this script , we can import this project into Eclipse.

Create and Compile required Java files
Add the following Java files to the com.mycompany.myproject package:
  • A Java interface named Cricketscore.
  • A Java class named CricketscoreImpl that extends the Cricketscore interface under impl folder.

Cricketscore.java
package com.mycompany.myproject;
 
public interface Cricketscore {
     
    //Returns array data that represents the live score updates
 public String[] getLivescore();
   
}

CricketscoreImpl.java

In this development article , we used the Apache HttpClient library which simplifies handling HTTP request.

We can retrieve and send data via the HttpClient class.An instance of this class can be created with new DefaultHttpClient().The HttpClient uses a HttpUriRequest to send and receive data.Important subclass of HttpUriRequest are HttpGet and HttpPost. By using HttpGet, we are getting response from http://static.cricinfo.com/rss/livescores.xml

We can get the response of the HttpClient as an InputStream. So below lines of code used to get response from service and by using BufferedReader & InputStreamReader we are processing that response to get XML data as String.

            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet getRequest = new HttpGet("http://static.cricinfo.com/rss/livescores.xml");
            getRequest.addHeader("accept", "application/xml");
            HttpResponse response = httpClient.execute(getRequest);
            if (response.getStatusLine().getStatusCode() != 200) {
                            throw new RuntimeException("Failed : HTTP error code : "
                                    + response.getStatusLine().getStatusCode());
            }
            BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));
            String score;
            String xmldata="" ;
            while ((score= br.readLine()) != null) {
                    xmldata= myJSON + score;
                }
            httpClient.getConnectionManager().shutdown();

Then by using XML parser (javax.xml.parsers & org.xml.sax.InputSource) , we are going to parse response data and extract required node items . Store these data in String array then return it to Client viewer.


             DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
             DocumentBuilder db = dbf.newDocumentBuilder();
             InputSource is = new InputSource();
             is.setCharacterStream(new StringReader(xmldata));
             Document doc = db.parse(is);
             NodeList nodes = doc.getElementsByTagName("item");
             String[] titles = new String[nodes.getLength()];
                // iterate the nodes
             for (int i = 0; i < nodes.getLength(); i++) {
                   Element element = (Element) nodes.item(i);
                   NodeList name = element.getElementsByTagName("title");
                   Element titlexml = (Element) name.item(0);
                   title =getCharacterDataFromElement(titlexml);
                   titles[i]=title;
             }
             return titles;
Here is the all lines of code for CricketscoreImpl.java

package com.mycompany.myproject;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import javax.xml.parsers.*;
import org.xml.sax.InputSource;
import org.w3c.dom.*;
import java.io.*;
import java.util.*;
 
//This is a component so it can provide or consume services
@Component  
    
@Service
 
public class CricketscoreImpl implements Cricketscore {
 protected final Logger log = LoggerFactory.getLogger(this.getClass());
    @Override
    public String[] getLivescore() {
        // TODO Auto-generated method stub
         
        try
        {
        
         String title = "";
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet getRequest = new HttpGet("http://static.cricinfo.com/rss/livescores.xml");
            getRequest.addHeader("accept", "application/xml");
            HttpResponse response = httpClient.execute(getRequest);
            if (response.getStatusLine().getStatusCode() != 200) {
              throw new RuntimeException("Failed : HTTP error code : " + response.getStatusLine().getStatusCode());
            }
            BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            String myXMLdata = "";
            String output;
            while ((output = br.readLine()) != null) {
             myXMLdata = myXMLdata + output;
            }
            httpClient.getConnectionManager().shutdown();
                        
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(myXMLdata));
            Document doc = db.parse(is);
            NodeList nodes = doc.getElementsByTagName("item");
            String[] titles = new String[nodes.getLength()];
            for (int i = 0; i < nodes.getLength(); i++)
            {
              Element element = (Element)nodes.item(i);
              NodeList name = element.getElementsByTagName("title");
              Element line = (Element)name.item(0);
              title = getCharacterDataFromElement(line);
              titles[i] = title;
            }
            return titles;
        }
        catch (Exception e)
        {
            e.printStackTrace() ; 
        }
        return null;
    }
    public static String getCharacterDataFromElement(Element e) {
        Node child = e.getFirstChild();
        if (child instanceof CharacterData) {
           CharacterData cd = (CharacterData) child;
           return cd.getData();
        }
        return "";
      }
  }


Next we need to add the Apache HttpComponents dependency in Maven POM file located at bundle folder in created project. So add below lines in POM.xml before end of  
</dependencies>.

<dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.1.1</version>
    </dependency>

Build and deploy the OSGi bundle using Maven 

Follow below steps to build the OSGi component,

i.Navigate to pom.xml located folder , then hold ctrl + shift then right-click to open cmd prompt from that folder
ii. Execute the maven command : mvn clean install
iii.After successful build, we can find OSGi bundle at (project folder)\bundle\target
iv.To deploy this bundle, open Apache Felix Console (http://server:port/system/console/bundles  )
v. In bundles tab, browse and install the created bundle under (project folder)\bundle\target
vi.After installing, reload and check bundle status must be Active. 

To display the webservice response , we need to follow below steps 

Open  (http://server:port/system/console/bundles  ) and create project as per below structure 

Create a template and Component

To display the component in page we need template, so first we will create a template  ,
1. Right-click the template folder within your application and select  Create -> Create Template and sling:resourceType to below created component path
2. Enter required information to create basic component and name the component as livescore 
3. Open livescore.jsp and paste below code to display Live Create Score

<@include file="/libs/foundation/global.jsp">
<cq:includeclientlib categories="jquerysamples"></cq:includeclientlib>
<html>
   <head>
         <!-- Below script used to reload page
            <script>
            $(document).ready(function(){
               setInterval(function(){cache_clear()},60000);
            });
            function cache_clear()
            {
              window.location.reload(true);
            }
         </script> -->

         <style>
            #page-wrap {
               width: 800px;
               margin: 0 auto;
               border: 3px solid #73AD21;
               padding: 10px;
               background-image:
                  linear-gradient(
                     to right, 
                     #0896A8,
                     #0896A8 15%,
                     #0896A8 15%,
                     #82C8D1 50%,
                     #82C8D1 50%
                  );
             }
         </style>
         <%
            com.mycompany.myproject.Cricketscore cs = sling.getService(com.mycompany.myproject.Cricketscore.class);
            String[] xmldata= cs.getLivescore() ; 
            request.setAttribute("xmldata", xmldata);
         %>
         <body>
           <div id="page-wrap">
              <h3>
Live Cricket Score Feed from CRICINFO</h3>
<hr />
              <c:foreach items="${xmldata}" var="xmldatascore">
                     <c:if test="${not empty xmldatascore}">
                        <strong><c:out value="${xmldatascore}"></c:out></strong><hr />
                     </c:if>
              </c:foreach>
           </div>
</body>
    </head>
</html>


In above code, i have added jquery to refresh the page for every 60 secs so include jquerysample Client libraries 

Create the web page to display Live Cricket Score from Cricinfo that based on the above created template.