Thursday, March 2, 2017

Time zone difference in Author/Publishers - Adobe CQ5/AEM

Time zone difference in Author/Publishers - Adobe CQ5/AEM

The timezone configured in the OS(Linux) level is CST but some time the log files displays the timezone in GMT

To fix the issue force the Adobe Experience Manager(AEM) server to use the required timezone in startup file(start.sh)
e.g.
CQ_JVM_OPTS='-server -Xmx1024m -XX:MaxPermSize=256M -Duser.timezone=US/Central -Djava.awt.headless=true'



Wednesday, March 1, 2017

How to protect the content from anonymous access through SAML based SSO - Adobe CQ5/AEM

How to protect the content from anonymous access through SAML based SSO - Adobe CQ5/AEM

How to enable SAML based SSO for publisher - Adobe CQ5/AEM
How to enable SAML based SSO in publisher to protect the content while accessing via dispatcher - Adobe CQ5/AEM

This post will explain the steps required to protect the published content from anonymous access through SAML based SSO while accessing via dispatcher/publisher - Adobe CQ5/AEM

Out of scope for this post - Configurations of IDP provider. Make sure the return URL configured in SAML provider is /saml_login

Enable Authentication for required content path:

Go to http://localhost:4503/system/console/configMgr(publisher)
Search for Apache Sling Authentication Service
Add the path that required the authentication to Authentication requirements in the following format +<<Content Path>> e.g. +/content/test


Configure the IDP certificate in Adobe Experience Manager(AEM):

Go to http://localhost:4503/system/console/configMgr(publisher)
Under /etc/key in the repository, create a node called "saml"(type nt:folder).
Inside this node, add a new binary property called  "idp_cert" for the public certificate of the IdP.
Upload the certificate file by double clicking on idp_cert property
Save All




Tuesday, February 28, 2017

How to generate sitemap for multi site environments? - Adobe CQ5/AEM

How to generate sitemap for multi site environments? - Adobe CQ5/AEM

This post will explain how to generate the sitemap for different sites(home pages) in multi site environment of Adobe Experience Manager(AEM).

The sitemap will be generated dynamically whenever user access the sitemap URL for particular site.

Factory servlet to generate the sitemap.xml:

import java.io.IOException;
import java.util.*;

import javax.servlet.ServletException;
import javax.xml.stream.*;

import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.felix.scr.annotations.*;
import org.apache.sling.api.*;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.commons.Externalizer;
import com.day.cq.wcm.api.*;

@Component(metatype = true, label = "Site Map", description = "Site Map", configurationFactory = true)
@Service
@SuppressWarnings("serial")
@Properties({
@Property(name = "sling.servlet.resourceTypes", unbounded = PropertyUnbounded.ARRAY,
label = "Homepage Resource Type", description = "Sling Resource Type for Home Page component"),
@Property(name = "sling.servlet.selectors", value = "sitemap", propertyPrivate = true),
@Property(name = "sling.servlet.extensions", value = "xml", propertyPrivate = true),
@Property(name = "sling.servlet.methods", value = "GET", propertyPrivate = true),
@Property(name = "webconsole.configurationFactory.nameHint",
value = "Site Map on resource types: [{sling.servlet.resourceTypes}]") })
public final class SiteMapGeneratorServlet extends SlingSafeMethodsServlet {

private static final Logger LOG = LoggerFactory.getLogger(SiteMapGeneratorServlet.class);
private static final FastDateFormat DATE_FORMAT = FastDateFormat.getInstance("yyyy-MM-dd");
private static final boolean INCLUDE_LAST_MODIFIED_DEFAULT_VALUE = false;

@Property(boolValue = INCLUDE_LAST_MODIFIED_DEFAULT_VALUE, label = "Include Last Modified Date",
description = "If checked, last modified value will be shown in sitemap.")
private static final String INCLUDE_LAST_MODIFIED_PROPERTY = "include.lastmod";

private static final String SITEMAP_NAMESPACE = "http://www.sitemaps.org/schemas/sitemap/0.9";

@Reference
private Externalizer externalizer;

private boolean incLastModified;

@Activate
protected void activate(Map<String, Object> properties) {
this.incLastModified = PropertiesUtil.toBoolean(properties.get(INCLUDE_LAST_MODIFIED_PROPERTY),
INCLUDE_LAST_MODIFIED_DEFAULT_VALUE);
}

@Override
protected void doGet(SlingHttpServletRequest slingRequest, SlingHttpServletResponse slingResponse)
throws ServletException, IOException {

slingResponse.setContentType(slingRequest.getResponseContentType());
ResourceResolver resourceResolver = slingRequest.getResourceResolver();
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
Page pageObj = pageManager.getContainingPage(slingRequest.getResource());

XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
try {
XMLStreamWriter stream = outputFactory.createXMLStreamWriter(slingResponse.getWriter());

stream.writeStartDocument("1.0");
stream.writeStartElement("", "urlset", SITEMAP_NAMESPACE);
stream.writeNamespace("", SITEMAP_NAMESPACE);

// Current page
writeXML(pageObj, stream, slingRequest);

for (Iterator<Page> children = pageObj.listChildren(new PageFilter(), true); children.hasNext();) {
Page childPage = (Page) children.next();
// If condition added to make sure the pages hidden in search in page properties do not show up in sitemap
if (null != childPage) {
if (!childPage.getProperties().containsKey("hideInSearch")
|| (childPage.getProperties().containsKey("hideInSearch")
&& childPage.getProperties().get("hideInSearch").equals("false"))
|| (childPage.getProperties().containsKey("hideInSearch")
&& childPage.getProperties().get("hideInSearch").equals("")))
writeXML(childPage, stream, slingRequest);
}
}

stream.writeEndElement();
stream.writeEndDocument();

} catch (XMLStreamException e) {
throw new IOException(e);
}
}

private void writeXML(Page pageObj, XMLStreamWriter xmlStream, SlingHttpServletRequest slingRequest)
throws XMLStreamException {
xmlStream.writeStartElement(SITEMAP_NAMESPACE, "url");

String protocolPort = "http";
if (slingRequest.isSecure())
protocolPort = "https";

String locPath = this.externalizer.absoluteLink(slingRequest, protocolPort,
String.format("%s.html", pageObj.getPath()));

writeXMLElement(xmlStream, "loc", locPath);

if (this.incLastModified) {
Calendar calendarObj = pageObj.getLastModified();
if (null != calendarObj) {
writeXMLElement(xmlStream, "lastmod", DATE_FORMAT.format(calendarObj));
}
}
xmlStream.writeEndElement();
}

private void writeXMLElement(final XMLStreamWriter xmlStream, final String elementName, final String xmlText)
throws XMLStreamException {
xmlStream.writeStartElement(SITEMAP_NAMESPACE, elementName);
xmlStream.writeCharacters(xmlText);
xmlStream.writeEndElement();
}

}

Create new servlet configuration from the factory through OSGI console by providing the following details

Home Page Resouce Type - add the Home page resource types that should be considered for generating sitemap.xml

Include Last Modified Date - If selected the last modified date of the page will be included as part of the sitemap.xml





Tuesday, February 21, 2017

How to exclude the replication agent from manual replication actions - Adobe CQ5/AEM?

How to exclude the replication agent from manual replication actions - Adobe CQ5/AEM?

Exclude the replication agent from manual replication actions in Adobe Experience Manager(AEM)- Sometimes we may required to exclude the specific replication agents from manual action but only the actions through workflow or API.

Enable "Ignore Default" in Triggers tab of Agent configuration wizard.




Sunday, February 19, 2017

How to display the dynamic popup in a page through GTM?

How to display the dynamic popup in a page through GTM?

This post will explain how to display the dynamic popup in a page through GTM.

The assumption is the required JQuery scripts are included as part of the page.

Define the cookie type variable:

This will help us to display the popup for every new browser session(this step is not required if the popup should displayed every time visiting the page)
  • Click on Variable in left hand side menu.
  • Go to user defined variables and select new.
  • Select variable configuration as 1st party cookie 
  • Give cookie name as popUpDisplayed and check url decode cookie option.
  • Save the changes and give the name as popUpDisplayed.