Featured

Wednesday, 1 June 2016

Custom xtype in cq5 / Creating multifield in AEM

In AEM we can achieve this by creating a widgets clienlibrary, which holds the custom multifield structure and it should call before the comps/page loads in CQ.

Create a clientlibrary in the root folder called apps. Here i am creating a folder called advtraining in apps. In this im creating the clientlibrary called "cqwidgets" having categories as "cq.widgets".

Now after creating this , place our custom multifield code in the created js file.

And Create a component for placing our custom xtype . And just drag the component in to the page and start using it.

Complete information @AEMBOOK  - Custom xtype in cq5 / Creating multifield in AEM

Cheers!!!

Saturday, 30 April 2016

How to use data-sly attributes in slghtly with AEM

Here we will discuss some scenarios which are related to using the data-sly attributes to specific HTML-elements.
We can use all the data-sly attributes everywhere you like.
These scenarios will explain, data-sly-list with HTML5 article and section tags

Scenrio-1:  
            <article data-sly-list="${currentPage.listChildren}">
  <section>
    <h1>${item.title}</h1>
    <h2>${item.properties.subtitle}</h2>
    <h3 data-sly-test="${item.listChildren}">My page has subpages</h3>
  </section>
</article>
 
Preserve the markup from the designer
How many times do you get a HTML snippet from a designer with some nice mock data in there? And what do we with that?, we rip it apart and you just end up with a small snippet and you lost the context of it.
Now with sightly you can preserve the markup including the mock data, and still make it fully functional.
In the scenario below I have received a navigation HTML snippet, and integrated this with sightly. Via the empty data-sly-test attributes the elements are suppressed completely.

Scenrio-2:
<ul data-sly-list="${currentPage.listChildren}">
  <li data-sly-text="${item.title}">This is the first menu item from my page</li>
  <li data-sly-test><a href="#">This is the second menu item from my page </a></li>
  <li data-sly-test><a href="#">This is the third menu item from my page </a></li>
  <li data-sly-test><a href="#">This is the fourth menu item from my page </a></li>
</ul>
 
Naming your data-sly-test expression:
With data-sly-test you can show or hide an HTML element.
What you also can do is to name your expression and reuse that in other data-sly-test expression.
In the scenario below I have data-sly-test-valid, that then can used as ‘valid’ in the other data-sly-test expression.

Scenrio-3:
<div data-sly-test.valid="${pageProperties.name}">${pageProperties.name}</div>
<div data-sly-test="${!valid && wcmmode.edit}">Please enter a name for this page</div>
Hiding container elements
If some cases you have a need to hide a container element, for example hiding the <ul> for a list, or not generating a surrounding <div>
For these cases you can use the data-sly-unwrap attribute.
In this example we generate a list of <li> items, without the <ul>.

Scenrio-4:
<ul data-sly-list.child="${currentPage.listChildren}" data-sly-unwrap>
  <li>${child.title}</li>
</ul>
You can also pass an expression to the data-sly-unwrapped attribute to make it conditional.
Here you see that only in edit-mode the <ul> is hidden.

Scenrio-5:
<ul data-sly-list-child="${currentPage.listChildren}" data-sly-unwrap="${wcmmode.edit}">
  <li>${child.title}</li>
</ul>
Custom Java-classes
In most projects you will find yourself in need to write some custom code to support your components. With sightly you can use the data-sly-use attribute for that.

Scenrio-6:
<div data-sly-use.comp1="com.myproject.SightlyComponent">
  <h1>${comp1.myTitle}</h1>
</div>
Java-class, option 1
We have a few options how you can write your custom class, the first option is that your Java-class is extending the “WCMUse” class from Sightly.
When extending this class you are able to call methods like “getResource()”, “getCurrentPage()”, “getPageManager()” etc.
Here an example of a Java-class that extends WCMUse.
SightlyComponent.java
                  public class SightlyComponent extends WCMUse  {
  private String myTitle;
  @Override
  public void activate() {
    myTitle = "My Project " + getCurrentPage().getTitle();
  }
  public String getMyTitle() {
    return myTitle;
  }
}
Java-class, option 2
If you don’t feel comfortable to extend a class, you can also implement the Use-interface.
Via the init() method you can access all the bindings that are available. These are things like “currentPage”, “resource”, “request” etc.
Here an example of this implementation.
SightlyComponent.java
                  public class SightlyComponent implements Use {
  private String myTitle;
  @Override
  public void init(Bindings bindings) {
    Page currentPage = (Page) bindings.get(WCMBindings.CURRENT_PAGE);
    myTitle = currentPage.getTitle() + "new";
  }
  public String getMyTitle() {
    return myTitle;
  }
}
We have some more options how you can implement Java-classes, but I will cover that in a next article.
In this final example you can see how you can access a service from the WCMuse-class
SightlyComponent.java
                  public class SightlyComponent extends WCMUse  {
  private String myTitle;
  @Override
  public void activate() {
    myTitle = "My Project " + getCurrentPage().getTitle();
    MyService service = getSlingScriptHelper().getService(MyService.class);
    service.action(myTitle);
  }
  public String getMyTitle() {
    return myTitle;
  }
}

We can explore more things about sightly in next article !!!
 
Cheers!!!
SonyCharan

Sightly api, comparing, accessing arrays with sightly in AEM

Here we will discuss about:
       ·          How to use arrays with slightly
       ·         How to compare
       ·         How to use API - Some scenarios

Arrays :
Here a sample around arrays:
// accessing a value from properties
${ properties['jcr:title'] }

// printing an array
${ aemComponent.names }

Printing the array, separated by ;
${ aemComponent.names @ join=';' }

// dynamically accessing values
<ul data-sly-list="${aemComponent.names}">
      <li>${ properties[ item ]}</li>
</ul>

Comparisons:
Here some use-cases on comparing values

<div data-sly-test="${ properties.jcr:title == 'test'}">TEST</div>
<div data-sly-test="${ properties.jcr:title != 'test'}">NOT TEST</div>

<div data-sly-test="${ properties['jcr:title'].length > 3 }">Title is longer than 3</div>
<div data-sly-test="${ properties['jcr:title'].length >= 0 }">Title is longer or equal to zero </div>

<div data-sly-test="${ properties['jcr:title'].length > aemComponent.MAX_LENGTH }">
Title is longer than the limit of ${aemComponent.MAX_LENGTH}
</div>

Now we will look at the API part and some scenarios here:

Use-API :
In my prvious article I explained that you can call methods from your custom-classes via the data-sly-use notation.
Now explaining, you can also pass in parameters from your components.
<div data-sly-use.aemComponent="${'com.myproject.components.SightlyComponent' @ firstName= 'feike', lastName = 'visser'}">
     ${aemComponent.fullname}
</div>

Java-code in the Use-Api
                    public class SightlyComponent extends WCMUse {
   // firstName and lastName are available via Bindings
  public String getFullname() {
    return get("firstName", String.class) + " " + get("lastName", String.class);
  }
}

The basic notation of the use-api looks like this is a Sightly component.

<div data-sly-use.mycomp="${ 'com.demo.MyComponent'
@ param1='value1', param2=currentPage}">
    ${mycomp.calculatedValue}
</div>

In this example you have the following:
  • the class ‘com.demo.MyComponent’ is instantiated
  • the name ‘mycomp’ is used
  • two parameters are passed to the class
  • the method getCalculatedValue() is called
  •  
Now let’s look at the implementation of this; you have 5(!) options to implement this:
  1. Class that implements the Use-interface
  2. Class that extends WCMUse-class
  3. Class that is adaptable from Resource (resource.adaptTo(YourClass))
  4. Class that is adaptable from SlingHttpServletRequest (request.adaptTo(YourClass))
  5. Sling models

Below I will do an example of each option, so you can see what is needed for each.
With all 5 scenarios you can switch the implementation without changing anything in your component.

Scenario-1: Class implementing Use-interface
In this case you need to implement init(), and do the all the logic in there. Via the bindings-object you can access all the objects also available on the component.
import io.sightly.java.api.Use;

public class MyComponent implements Use {
  private String value;
  @Override
  public void init(Bindings bindings) {
    // all standard objects/binding are available
    Resource resource = (Resource) bindings.get("resource");
    // parameters are passed as bindings
    String param1 = (String) bindings.get("param1");
    Page param2 = (Page) bindings.get("param2");
    value = param1 + resource.getPath() + param2.getTitle();
  }

  public String getCalculatedValue() {
    return value;
  }
}

Scenario-2: Class extending WCMUse
This option is similar like the Use-interface, but has some more helper functionality that you can use. Methods like getResource(), getCurrentPage() etc are already there for you to use.
import com.adobe.cq.sightly.WCMUse;

public class MyComponent extends WCMUse {
  private String value;

  @Override
  public void activate() {
    // helper method to get the default bindings
    Resource resource = getResource();
    // access to the parameters via get()
    String param1 = get("param1", String.class);
    Page param2 = get("param2", Page.class);
    value = param1 + resource.getPath() + param2.getTitle();
  }

  public String getCalculatedValue() {
    return value;
  }
}
Scenario-3: Class adaptable from Resource
Code example given here is how to adapt your class from a Resource. Based on that Resource-object you need to pass in the right info to your POJO. In this case you can have a plain POJO without any dependency to AEM or Sightly.
NOTE: In this option you can’t access the parameters
@Component(metatype = true, immediate = true)
@Service
public class MyComponentAdapter implements AdapterFactory {

  @Property(name = "adapters")
  protected static final String[] ADAPTER_CLASSES = { MyComponent.class.getName() };

  @Property(name = "adaptables")
  protected static final String[] ADAPTABLE_CLASSES = { Resource.class.getName() };

  @Override
  public <AdapterType> AdapterType getAdapter(Object adaptable, Class<AdapterType> type) {
    if (adaptable instanceof Resource) {
       MyComponent comp = new MyComponent();
       return (AdapterType) comp;
    }
    return null;
  }
}
Scenario-4: Class adaptable from Request
Like option 3, but now based on the request. Also it is possible here to access the parameters; they are passed in as attributes.
@Component(metatype = true, immediate = true)
@Service
public class MyComponentAdapter implements AdapterFactory {

  @Property(name = "adapters")
  protected static final String[] ADAPTER_CLASSES = { MyComponent.class.getName() };

  @Property(name = "adaptables")
  protected static final String[] ADAPTABLE_CLASSES = { SlingHttpServletRequest.class.getName() };

  @Override
  public <AdapterType> AdapterType getAdapter(Object adaptable, Class<AdapterType> type) {
    if (adaptable instanceof SlingHttpServletRequest) {
      SlingHttpServletRequest request = (SlingHttpServletRequest) adaptable;
      String param1 = (String) request.getAttribute("param1");
      Page param2 = (Page) request.getAttribute("param2");
      return (AdapterType) new MyComponent();
    }
    return null;
  }
}
Scenario-5: Sling Models
You can technically implement Options 3 and 4 with Apache Sling Models; this saves you from creating your own adapters. Here’s an example of what that would look like:
@Model(adaptables=Resource.class)
public class MyComponent {

  @Inject
  private String firstname;
  private String value;

  @PostConstruct
  public void activate() {
    value = "calculate " + firstname;
  }

  public String getCalculatedValue() {
    return value;
  }
}
Use these test case scenarios and explore slightly !!!


Cheers!!!

SonyCharan

How to use Sightly in AEM


Sightly Introduction:

Sightly can referred as an HTML templating language, introduced with the version AEM 6.0.

It takes the place of JSP (Java Server Pages) and ESP (ECMAScript Server Pages) as the preferred templating system for HTML. The name “Sightly” (meaning “pleasing to the eye”) highlights its focus on keeping your markup beautiful, and thus maintainable, once made dynamic.
As in all HTML server-side templating systems, a Sightly file defines the output sent to the browser by specifying the HTML itself, some basic presentation logic and variables to be evaluated at runtime.

Why we use Sightly,

·         Security by Default
·         Separation of Concerns
·         Sightly is HTML5

How to use Sightly:

Every Sightly file is an HTML5 document or fragment, augmented with a specific syntax that adds the dynamic functionality. Here's a first example:
<h1 data-sly-test="${properties.jcr:title}">
${properties.jcr:title}
</h1>
Two different kind of syntaxes have to be distinguished:
  • Sightly Block Statements
    To define structural block elements within Sightly file, Sightly employs HTML5 data attributes. This allows to attach behavior to existing HTML elements. All Sightly-specific attributes are prefixed with data-sly-.
  • Sightly Expressions
    Sightly expressions are delimited by characters ${ and }. At runtime, these expressions are evaluated and their value is injected into the outgoing HTML stream. They can occur within the HTML text or within HTML attribute values.

<p data-sly-use.logic="logic.js">
    <a href="${logic.link}">
        ${logic.text}
    </a>
</p>

<h1 data-sly-test="${currentPage.title}">
    <a href="${currentPage.path}.html">
        ${currentPage.title}
    </a>
</h1>

Explanation for better understanding:
  • Line 1: The data-sly-test statement checks if the page title exists and is not empty. If so, the <h1> element and its content is displayed, otherwise it is removed altogether.
  • Line 2: This expression renders the page path into the href attribute. Since Sightly knows the HTML syntax, href and src attributes are automatically protected against cross-site scripting (XSS) injections accordingly. For instance if the variable contained a javascript: URL, it would have been removed.
  • Line 3: This expression displays the page title as text. Many special characters are escaped to make it impossible to inject cross-site scripts.

The main goals /objectives of sightly are :
        – giving back the markup, and not mixing it with code
        – everything is secure, by default
        – smoothen the workflow between the designer and the developer

Scenario-1:
<div>currentPageTitle : ${currentPage.title}</div>

  • Well that looks like a JSP, but not quite. Two main differences:
  • Extension of the file is changed to .html
  • We have only markup in the file, no inclusion of a global.jsp, just markup. So in case a designer wants to look at the file he can just open it in his tools

Scenario-2:
<div data-sly-test="${wcmmode.edit}">Showing this only in edit mode to the author</div>
When the expression inside data-sly-test evaluates to false the whole tag while be hidden in the markup.

Scenario-3:
<div data-sly-test.author="${wcmmode.edit || wcmmode.design}">
Show this to the author
</div>
<div data-sly-test="${!author}">
Not in author mode anymore.
</div>
data-sly-test also supports the naming and reuse of tests, we have an expression ‘author’ that we want to reuse in other data-sly-test attributes.
These are very common use-cases and can now be done without writing any code are extension.

Scenario4:
                    <div data-sly-text="${currentPage.title}">My page title</div>

data-sly-text will replace the value of the HTML-element with the expression of the data-sly-text.
In the example above the page-title will be printed. But the mock value can still be in there to make it easier to view the file in HTML-editors.
 
Scenario-5:
                    <ul data-sly-list.child="${currentPage.listChildren}">
                               <li>${child.title}</li>
                    </ul>
Here you see an example of a loop, the list object is passed to the data-sly-list attribute. Based on the name (‘child’) you can reference each item in the loop.The output is here that see you a list of the subpages with all the page-titles.

Scenario-6:
<ul data-sly-list.child="${currentPage.listChildren}">
          <li class="${ childList.odd ? 'odd' : 'even'}">${child.title}</li>
</ul>

Observations are:
  1. inside a data-sly-list you have access to a list-variable that contain things like : index, count, odd, even, first, last, middle
  2. in the expression you see the use of the ternary operator

Scenario-7:
                    <div data-sly-resource="${ @path='par', resourceType='foundation/components/parsys'}"></div>
With data-sly-resource you can include components and resources. In the above sample you include of standard cq parsys in your template.

Scenario-8:
    <footer data-sly-resource="${ @ path='footer', resourceType='myproject/footer', wcmmode='disabled'}"></footer>
So you are in need to disable the wcmmode for a specific component? That can now be done via the wcmmode-option when including a component.

Scenario-9:
                    ${pageProperties.jcr:title || properties.title || "No title"}
Within an expression you can use the ‘or’ operator to define fallbacks in case properties are empty. You read the expression from left to right, in the example here “No title” is shown when jcr:title and properties.title are both empty.

Scenario-10:
<div data-sly-include="/libs/wcm/core/components/init/init.jsp"></div>
 
<div data-sly-include="mytestfile.html"></div>

Via data-sly-include you can include other files like the cq:include tag. From sightly you can still use and re-use JSP files if you want. Like shown here for the author-environment.

We will discuss more in detail in our next posts.

Cheers!!!
SonyCharan

Tuesday, 5 January 2016

Servlets in CQ5 | How to write/register servlets in CQ5

      Initially the Servlet API specification states the following with respect to the life cycle of Servlets:

       The servlet container calls the init method exactly once after instantiating the servlet.
This works perfectly in a regular servlet container which both instantiates and initializes the servlets. With Sling the tasks of instantiation and initialization are split:
  • The provider of the Servlet service takes care of creating the servlet instance
  • The Sling Servlet Resolver picks up the Servlet services and initializes and destroys them as needed
     So Sling has not way of making sure a Servlet is only initialized and destroyed once in the life time of the Servlet object instance.
The provider of the Servlet service on the other can cope with this situation by making sure to drop the servlet instance once it is destroyed. The mechanism helping the provider here is the OSGi Service Factory.

Registering a Servlet : 


     Servlets can be registered as OSGi services. The following service reference properties are defined for Servlets defined as OSGi services of type javax.servlet.Servlet:
  • sling.servlet.paths
  • sling.servlet.resourceTypes
  • sling.servlet.selectors
  • sling.servlet.extensions
  • sling.servlet.methods
  • sling.servlet.prefix

        A SlingServletResolver listens for Servlet{}services and - given the correct service registration properties - provides the servlets as resources in the (virtual) resource tree. Such servlets are provided as ServletResource instances which adapt to the javax.servlet.Servlet class.

        For a Servlet registered as an OSGi service to be used by the Sling Servlet Resolver, either or both of the sling.servlet.paths or the sling.servlet.resourceTypes service reference properties must be set. If neither is set, the Servlet service is ignored.

        Each path to be used for registration - either from the sling.servlet.paths property or constructed from the other sling.servlet.\* properties - must be absolute. Any relative path is made absolute by prefixing it with a root path. This prefix may be set with the sling.servlet.prefix service registration property. If this property is not set, the first entry in the ResourceResolver search path for the ResourceResolver.getResource(String) method is used as the prefix. If this entry cannot be derived, a simpe slash - / - is used as the prefix.

       If sling.servlet.methods is not specified, the servlet is only registered for handling GET requests. Make sure to list all methods you want to be handled by this servlet.


Registering a Servlet using Java Annotations


      If you are working with the default Apache Sling development stack you can use Java Annotations from Apache Felix Maven SCR Plugin to register your Sling servlets and describe their binding details.

sling.servlet.paths = \[ "/libs/sling/sample/html", "/libs/sling/sample/txt" \]
sling.servlet.resourceTypes = \[ "sling/unused" \]
sling.servlet.selectors = \[ "img" \]
sling.servlet.extensions = \[ "html", "txt", "json" \]


      These are the ways of doing , either with a Sling-specific @SlingServlet annotation or with the more generic maven-scr-plugin annotations etc..

1) The @SlingServlet annotation


@SlingServlet(
    resourceTypes = "sling/servlet/default",
    selectors = "hello",
    extensions = "html",
    methods = "GET")
public class MyServlet extends SlingSafeMethodsServlet {

    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        ...
    }
}


2) The @Properties and @Property annotations


@Component(metatype = true)
@Service(Servlet.class)
@Properties({
    @Property(name = "sling.servlet.resourceTypes", value = "sling/servlet/default"),
    @Property(name = "sling.servlet.selectors", value = "hello"),
    @Property(name = "sling.servlet.extensions", value = "html"),
    @Property(name = "sling.servlet.methods", value = "GET")
})
public class MyServlet extends SlingSafeMethodsServlet {

    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        ...
    }
}

Upon these we can define in following ways too

3) Registering the servlet by path


@SlingServlet(
    paths={"/services/unicom/v1/"}
)
@Properties({
    @Property(name="service.pid", value="com.adobe.unicom.v1.servlets.OmnnitureLoggingServlet",propertyPrivate=false),
    @Property(name="service.description",value="Omniture service call logging servlet", propertyPrivate=false),
    @Property(name="service.vendor",value="Adobe Systems Incorporated - Adobe@Adobe Team", propertyPrivate=false)
})
public class OmnnitureLoggingServlet extends SlingAllMethodsServlet
{
    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException
    {
        //Do something fun here
    }
    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException
    {
        //Do something fun here
    }
}

4) Registering the servlet by resource type and extension


@SlingServlet(
    resourceTypes = {"rep:User"},
    methods = {"GET", "POST"}
)
@Properties({
    @Property(name="service.pid", value="com.adobe.unicom.v1.servlets.OmnnitureLoggingServlet",propertyPrivate=false),
    @Property(name="service.description",value="Omniture service call logging servlet", propertyPrivate=false),
    @Property(name="service.vendor",value="Adobe Systems Incorporated - Adobe@Adobe Team", propertyPrivate=false)
})
public class OmnnitureLoggingServlet extends SlingAllMethodsServlet
{
    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException
    {
        //Do something fun here
    }
    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException
    {
        //Do something fun here
    }
}

5) handle all requests and filter on selector you can change the example above to read something like this.


@SlingServlet(
    resourceTypes = {"sling/servlet/default"},
    methods = {"GET"},
    selectors = {"report"},
    extensions = {"json"}
)
@Properties({
    @Property(name="service.pid", value="com.adobe.unicom.v1.servlets.OmnnitureLoggingServlet",propertyPrivate=false),
    @Property(name="service.description",value="Omniture service call logging servlet", propertyPrivate=false),
    @Property(name="service.vendor",value="Adobe Systems Incorporated - Adobe@Adobe Team", propertyPrivate=false)
})
public class OmnnitureLoggingServlet extends SlingAllMethodsServlet
{
........
}

6) To handle all requests for a Page with a special selector.


ie http://www.demosample.com/content/page.mycustomselector.html  

@SlingServlet(
    resourceTypes = {"cq:Page"},
    methods = {"GET"},
    selectors = {"mycustomselector"}
)
@Properties({
    @Property(name="service.pid", value="com.adobe.unicom.v1.servlets.OmnnitureLoggingServlet",propertyPrivate=false),
    @Property(name="service.description",value="Omniture service call logging servlet", propertyPrivate=false),
    @Property(name="service.vendor",value="Adobe Systems Incorporated - Adobe@Adobe Team", propertyPrivate=false)
})
public class OmnnitureLoggingServlet extends SlingAllMethodsServlet
{
........
}

7) To handle all requests for a Page with a special extension.


ie http://www.demosample.com/content/page.mydemoext 

@SlingServlet(
    resourceTypes = {"cq:Page"},
    methods = {"GET"},
    extensions = {"mydemoext"}
)
@Properties({
    @Property(name="service.pid", value="com.adobe.unicom.v1.servlets.OmnnitureLoggingServlet",propertyPrivate=false),
    @Property(name="service.description",value="Omniture service call logging servlet", propertyPrivate=false),
    @Property(name="service.vendor",value="Adobe Systems Incorporated - Adobe@Adobe Team", propertyPrivate=false)
})
public class OmnnitureLoggingServlet extends SlingAllMethodsServlet
{
........
}

By following these can define/achieve creation of servlets in cq5 as per our tech specs.  

     Here we can prefer resourceType for writing SlingServlets most efficiently.
Some of the reasons comes into picture while development phase itself.

There are :
  • While defining a path , you must be specific what all paths are allowed to be used in the ServletResource OSGi service. If you define something randomly, your servlet might not be fucntional. Only a limited paths are allowed and the rest are blocked unless you open them up. This is resolved using resourceType.
  • You may have also configure the dispatcher , if you use some random path for your servlet. This might be a potential security threat and a needless configuration.
  • You might also have to specify the paths to your consumers for your servlet and any change in that path could have a serious affect. This might not be the case when you use resourceType
Thanks,
SonyCharan