Author Archive: sbhaskar

Why AEM?

iconAdobe Experience Manager (AEM) manages the user experience of your website (content) across various channels. In a globalized world, you need to manage content across multiple websites in various languages. Your content is consumed using various devices – hand-held devices, such as mobile phones and tablets, PCs, and so on. This results in a scenario that you have plenty of user experiences to manage. You need to provide optimal experience in both iPhones and Android phones. And, the same is applicable across thousands of other devices. AEM helps you to achieve this goal effectively and effortlessly.

AEM is one of the solutions in Adobe’s Marketing Cloud ecosystem. All solutions in Marketing Cloud complement each other and provide you with key solutions to effectively manage user experiences. The following diagram represents various solutions in Adobe Marketing Cloud: (Taken from Adobe’s website.)

marketing_cloud

Let me cite a few examples for how this ecosystem helps you to provide better user experience.

I am sure all of us would have visited online shopping sites many times. Which is the most commonly used feature in an online shopping site, such as Amazon? It definitely is the Search feature. You normally won’t traverse through menu options such as Men’s and then Boots,  …. and so on. You just search for the product you need. There can be thousands of users who do the same thing while you search for a product. For online shopping sites, the Search feature must be very efficient. Adobe Marketing Cloud provides you with a solution named Site Search. You can easily integrate Site Search with AEM. This capability indexes all your products and details, as Google indexes a website information. When a user searches for a product, the Site Search provides the search result and makes this operation extremely fast.

Similarly, tracking your users is very important to serve them better. You need to know the geographical areas they come from, the web pages they visit, and so on. AEM can be integrated with Adobe Analytics easily. This gives you a great reporting capability and statics about your user behavior.

Content personalization is another important aspect of your website. You should be able to customize your website based on your user profile. If your user is a male of a certain age group, provide the user with something he finds appealing. Change it accordingly if the user is a female of a certain age group. Adobe’s Marketing Cloud solution, Adobe Target, does it for you effortlessly.

Adobe Social (a capability in Marketing Cloud solution) helps you to integrate AEM with Social Media. Adobe Campaign allows you to manage digital campaign effortlessly. In short, AEM along with other Marketing Cloud solutions helps you to provide a great digital experience to your users. It indeed transforms your content into experiences that result in better customer reach, retention, and high ROI.

In the next post, you will see the underlying technologies on AEM.

Adobe Lightroom for Android

Adobe Lightroom for Android is available today.
For more details, see the official blog.

 

AEM Sightly Brackets Extension

You can install this extension on Brackets if you plan to use Sightly as the markup. The extension provides you with features such as syntax highlighting and code completion.

Brackets extension provides front-end developers an AEM templating tool with which they are familiar. The idea is to bring more front-end developers to AEM template designing. Use CRXDE Lite to create a basic structure of your project. Then create a package and download the package. Unzip the package and open it in Brackets. Make the changes; Brackets extension allows you to automatically sync with the Oak repository.

For more information, see Adobe’s documentation.

While creating templates for Touch-Optimized GUI

In AEM 6.0, most of the functionalities are accessible through Touch-Optimized UI. When you create a template using Sightly or JSP, before extending the page component, the Classic UI displays the content in a page created based on the template. Of course, the page is displayed without the sidekick and other functionalities.

 

This behavior, however, changes with Touch-Optimized UI. To appear page’s content in Touch-Optimized GUI, the page’s template should extend the page component using sling:ResourceSuperType . You can extend a Sightly or JSP page component to a template. It’s irrespective of the templating language (Sightly \ JSP).

Slightly, some Sightly

AEM 6.0 introduces Sightly – a new templating language. Sightly replaces JSP as the most preferred templating language for AEM. Sightly helps you to separate your design from your code. The intention is to bring more front-developers to AEM component development. By providing a demarcation between the design and the development departments, Adobe expects to reduce the go-to-market time for AEM development projects.

For more information on Sightly, visit Adobe documentation.

Sightly can used in three ways:

  • Pure HTML
  • HTML + server-side JavaScript
  • HTML + Java

In the following example, Sightly is used as pure HTML to display the name of a page:

Code in template

<h1>Page Title</h1>
<p>${currentPage.Title}</p>

The same example can be rewritten in Sighlty and JavaScript. This example doesn’t represent the best practice. However, it shows how to demarcate the logic using JavaScript:

Code in template

<div class="component-name" data-sly-use.component="component.js">
<h1>Page Title</h1>
${component.title}</div>
</div>

component.js

use(function() 
{
        return {
        title: currentPage.getTitle()
        };
});

The next example shows how the same logic is implemented using Sightly + Java combination:

Code in template

<div class="component-name" data-sly-use.component="Component">
<h1>Page Title</h1>
<p>${component.CurrentPageTitle}</p>
</div>

Component.java

package apps.your.directory.structure;
import com.adobe.cq.sightly.WCMUse;
import com.day.cq.wcm.api.Page;
public class Component extends WCMUse
{
private String CurrentPageTitle;

@Override
   public void activate() throws Exception 
   {
   final Page currentPage = getCurrentPage();
   CurrentPageTitle=currentPage.getTitle();
   }

   public String getCurrentPageTitle()
   {
   return CurrentPageTitle;
   }
}

Integrating Search&Promote with AEM

Search&Promote allows you to create an index of your site by crawling your site in a regular interval. It helps you to implement powerful search functionalities in your website. In AEM 5.6.1, there are some out-of-the-box Search&Promote components that make integration easy. Some of these components use hardcoded values that you may need to change in the component’s JSP page. You need to work with a Search&Promote consultant and understand the xml format, specifically the fieldnames, in which the results are provided.  Use the fieldnames in the JSP pages.

For example, if the fieldname for product description in the xml file is “desc,” rewrite the method in the Search Results component’s JSP page as:
r.get(“desc”)

Note: Search&Promote components are available at libs/cq/searchpromote/components.

Watch out AEM 6.0 release that is scheduled to be in May end. It has some cool integration workflows to avoid these workarounds.

Using the Target component in AEM 5.6.1

The Target component in AEM 5.6.1 allows you to create an MBox in your page and then create various experiences. It works like the Targeting feature provided with the context menu. You would have noticed that after you drag and drop the Target component to a page, the component becomes invisible.

To make the Target component visible in the page, bring up Client Context and associate it with a Campaign.

blog

Accessing previous versions of a page using CRXDE Lite

You can access the previous version of a page using CRXDE Lite:

  1. Login to CRXDE Lite.
  2. Move to the page for which you created versions.
    It would be present in the /content folder.
  3. Examine the jcr:content node of the page.
  4. Click the value of the jcr:versionHistory property.
    It will take you to the node that has all the versions you created.

Issues while importing a product catalog from Hybris to AEM

I faced some issues while importing a product catalog from Hybris to AEM with the 5.6.100 packages. The following were the error messages:

  • Cannot server request to /libs/commerce/products
  • Cannot serve request to ProductDataServelet

Recently, Adobe has released packages of version 5.6.200. I didn’t face the issue with these packages. If you face these issues, use the latest packages.

Developing a multifield widget for a CQ component

I had to develop a multifield widget for a CQ component. My requirement was to present the What’s New documents for a product’s releases. There could be many releases in an year. These need to be captured in a table row. A product release is associated with a specific product name and a What’s New URL.

To cut the story short, let me present you with some screenshots. The following is the dialog box where a user enters the release information:

component_edit

In this case, in an year, the product had two releases. One in March and the second one in Dec. The details are displayed as follows in the publish instance:

result

March being the third month, it’s displayed in the third column, and for the obvious reason, Dec is displayed in the 12th column. It displays the release name as a hyperlink to the What’s New doc.

Follow these steps to develop this widget:

  1. Install the Custom Multifield Widget. Follow Adobe’s instructions on how to do it. We will develop the component based on the Custom Multifield Widget that you will install as
    a part of the instructions.
  2. Copy the extjstraining/clientlib folder to your app/yourCompany folder, where you want to develop your component.
  3. Create a component in yourCoumpany folder.
  4. Now, expand to the extjstraining/components/customwidgets folder.
  5. Expand the multifield dialog box.
  6. Copy the multi node to your component’s dialog.
    multi_node
  7. Change the xtype of the node that you copied in the fieldConfig as follows:
    xtype
  8. In yourCompany folder, open the clientlib/js/CustomWidget.js file.
    1. Add one more text field as follows:
      //new textfield start
      this.allowText = new CQ.Ext.form.TextField({

      cls:”ejst-customwidget-2″,

      listeners: {

      change: {

      scope:this,

      fn: this.updateHidden

      }

      }

      });
      this.add(this.allowText);

      //end
    2. Set value for the new text field as follows:
      // overriding CQ.form.CompositeField#setValue

      setValue: function(value) {

      var parts = value.split(“/”);

      this.allowField.setValue(parts[0]);

      this.allowText.setValue(parts[1]);

      this.otherField.setValue(parts[2]);

      this.hiddenField.setValue(value);

      },

    3. Change the xtype as follows:
      // register xtype
      CQ.Ext.reg(‘ejstcustom1′, Ejst.CustomWidget);
  9. In yourCompany folder, open the clientlib/js/exercises.js file. Upadate the provider options for the drop-down list as follows:
    providerOptions
  10. Now, you can create the component’s JSP to format the values entered by the author:
    PropertyIterator propertyIterator= currentNode.getProperties();

    while(propertyIterator.hasNext())

    {

    Property currentProperty=propertyIterator.nextProperty();

    String currentValue=””;
    if(currentProperty!=null &&
    currentProperty.getName()!=null &&
    currentProperty.getName().toLowerCase().compareTo(“multi”)==0)

    {

    if(currentProperty.isMultiple())

    {

    Value[] values=currentProperty.getValues();
    String[] months={“Jan”,”Feb”,”March”,”April”,”May”,”June”,”July”,”Aug”,”Sep”,”Oct”,”Nov”,”Dec”};
    int[] table=new int[12];
    String[] version=new String[12];
    int k=0;

    for(Value value:values)
    {
    currentValue=value.getString();
    String[] splitValue=currentValue.split(“/”);

    for (int i=k; i<months.length; i++)
    {
    if (splitValue[0].equals(months[i]))
    {
    table[i]=1;
    version[i]=splitValue[1];
    }

    }

    }

    for (int m=0; m<table.length; m++)
    {
    if (table[m] == 1)
    {
    out.write (“<td>”+version[m]+”</td>”);
    }
    else
    {
    out.write(“<td>”+” “+”</td>”);
    }

    }
    }

    else
    {
    currentValue=currentProperty.getString();
    }

    }
    properties.isEmpty();
    }
    %>

  11. Test the component.