Sunday, 14 July 2019

Publish AEM Content to Salesforce Communities using CMS Connect

Salesforce has come up with a feature to connect the third-party Content management systems with Salesforce communities. You can connect CMS components, HTML, JSON, CSS, and JavaScript to customize your community and keep its branding consistent with your website. CMS connect feature renders content dynamically from CMS systems.


CMS Connect supports content from different CMS systems like AEM, Sitecore, Drupal, SDL, WordPress and Other.


Let's see how to pull content from AEM to Salesforce community.

Enable CORS in AEM

From AEM 6.3, Adobe added Cross-Origin Resource Sharing Policy (CORS) as OSGi configuration. CORS configurations can be added as an OSGi config factories.

CORS configurations are managed as OSGi configuration factories in AEM, with each policy being represented as one instance of the factory.
  • Navigate to http://localhost:4502/system/console/configMgr
  • Search for Adobe Granite Cross Origin Resource Sharing Policy (com.adobe.granite.cors.impl.CORSPolicyImpl)
Click here to check how to enable CORS for older AEM versions (<6.3)

Monday, 8 July 2019

Nested Multifield (coral 3) with Sling Model in AEM

Create AEM multi module project using archtype 11
Create a new component with cq:dialog for Touch UI as shown below.


<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
    jcr:primaryType="nt:unstructured"
    jcr:title="Country Details"
    sling:resourceType="cq/gui/components/authoring/dialog">
    <content
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
        <items jcr:primaryType="nt:unstructured">
            <column
                jcr:primaryType="nt:unstructured"
                sling:resourceType="granite/ui/components/coral/foundation/container">
                <items jcr:primaryType="nt:unstructured">
                    <countries
                        jcr:primaryType="nt:unstructured"
                        sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
                        composite="{Boolean}true"
                        fieldLabel="Countries">
                        <field
                            jcr:primaryType="nt:unstructured"
                            sling:resourceType="granite/ui/components/coral/foundation/container"
                            name="./countries">
                            <items jcr:primaryType="nt:unstructured">
                                <column
                                    jcr:primaryType="nt:unstructured"
                                    sling:resourceType="granite/ui/components/coral/foundation/container">
                                    <items jcr:primaryType="nt:unstructured">
                                        <countryName
                                            jcr:primaryType="nt:unstructured"
                                            sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                            fieldLabel="Country Name"
                                            name="./countryName"/>                                        
                                        <states
                                            jcr:primaryType="nt:unstructured"
                                            sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
                                            composite="{Boolean}true"
                                            fieldLabel="States">
                                            <field
                                                jcr:primaryType="nt:unstructured"
                                                sling:resourceType="granite/ui/components/coral/foundation/container"
                                                name="./states">
                                                <items jcr:primaryType="nt:unstructured">
                                                    <column
                                                        jcr:primaryType="nt:unstructured"
                                                        sling:resourceType="granite/ui/components/coral/foundation/container">
                                                        <items jcr:primaryType="nt:unstructured">
                                                            <stateName
                                                                jcr:primaryType="nt:unstructured"
                                                                sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                                fieldLabel="State Name"
                                                                name="./stateName"/>
                                                            <statePostal
                                                                jcr:primaryType="nt:unstructured"
                                                                sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                                fieldLabel="State Postal"
                                                                name="./statePostal"/>
                                                            <statePopulation
                                                                jcr:primaryType="nt:unstructured"
                                                                sling:resourceType="granite/ui/components/coral/foundation/form/numberfield"
                                                                fieldLabel="State Population"
                                                                name="./statePopulation"/>
                                                            <stateDensity
                                                                jcr:primaryType="nt:unstructured"
                                                                sling:resourceType="granite/ui/components/coral/foundation/form/select"
                                                                fieldDescription="Select State Density"
                                                                fieldLabel="State Density"
                                                                name="./stateDensity">
                                                                <items jcr:primaryType="nt:unstructured">
                                                                    <high
                                                                        jcr:primaryType="nt:unstructured"
                                                                        text="High"
                                                                        value="high"/>
                                                                    <medium
                                                                        jcr:primaryType="nt:unstructured"
                                                                        text="Medium"
                                                                        value="medium"/>
                                                                    <low
                                                                        jcr:primaryType="nt:unstructured"
                                                                        text="Low"
                                                                        value="low"/>                                                                    
                                                                </items>
                                                            </stateDensity>
                                                        </items>
                                                    </column>
                                                </items>
                                            </field>
                                        </states>
                                    </items>
                                </column>
                            </items>
                        </field>
                    </countries>
                </items>
            </column>
        </items>
    </content>
</jcr:root>



Now create slingmodels to get the authored values.
  1. CountriesModel.java
  2. Country.java
  3. State.java

Tuesday, 2 July 2019

Avoid encoding dispatcher URLs

Rewrite rules on Apache web server that attempt to redirect to URLs with special characters such as & or ? or #anchor aren't being redirected properly.  For example:
RewriteRule ^/we-retail.html /we-retail.html#anchor [R=301,L]

To avoid encoding the # character, add the NE flag to the rewrite rules:
RewriteRule ^/test.html /test.html#anchor [NE,R=301,L]

Special characters such as & and ?, will be converted to their hexcode equivalent. Using the [NE] flag prevents that from happening.
RewriteRule ^/anchor/(.+) /bigpage.html#$1 [NE,R]

The above example will redirect /anchor/xyz to /bigpage.html#xyz. Omitting the [NE] will result in the # being converted to its hexcode equivalent, %23, which will then result in a 404 Not Found error condition.
Reference: RewriteRule Flags

Remove .html extension at dispatcher

Add below dispatcher configurations in dispatcher.any file to remove .html extension from the URL.
#Enable RewriteEngine

RewriteEngine on


#Map the root folder to the home page

RewriteRule ^/?$ /content/we-retail/us/en/home.html [PT,L]


# remove any trailing slash, if it's there.

RewriteRule ^(.+)/$ $1


#Remove .html Extension

RewriteRule ^(.*).html$ $1 [R,L]


#Shorten the URL

RewriteRule ^/content/we-retail/us/(.*)$ $1 [R,L]


#Remove .html and map products url

RewriteRule ^/en/products.html/(.*)$ /en/products/$1 [R,L]


RewriteCond %{REQUEST_URI} !^/(apps|content|etc|home|libs|system|tmp|var|services)

RewriteRule ^/en/products/(.*)$ /content/we-retail/us/en/products.html/$1 [PT,L]


RewriteCond %{REQUEST_URI} !^/(apps|content|etc|home|libs|system|tmp|var|services)

RewriteRule ^/(.*)$ /content/we-retail/us/$1.html [PT,L]

Tuesday, 11 June 2019

Disable location tracker in AEM

Location tracker popup is annoying when page is loaded. This is enabled by default when clientcontext is used. 

Steps to disable location tracker:

  • Copy clientcontext component /etc/clientcontext/default to /etc/clientcontext/custom
  • Open this new component and delete the geolocation component.
  • Map this new component path to your design path ex: /etc/designs/default/jcr:content/homepage
We can see location tracker is disabled for specific site now.

Sunday, 13 January 2019

Targeting content in AEM

AEM enables to target content for different audience.

This post will explain how to target title component to display content based on user's location and do A/B testing.

Create a web page called Target under we-retail website.


Click here to check how to enable ContextHub.
Navigate to AEM instance and create Brand and activities. 


Saturday, 12 January 2019

Cannot read property 'extend' of undefined': ContextHub

While adding ContextHub to AEM site could see below errors

Change ContextHub entry in head section from 
<sly data-sly-resource="${'contexthub' @ resourceType='granite/contexthub/components/contexthub'}"/>

to 

!--/* Include Context Hub */-->
<sly data-sly-call="${clientlib.js @ categories='granite.utils'}"/>
<sly data-sly-resource="${'contexthub' @ resourceType='granite/contexthub/components/contexthub'}"/>


Click here to check how to setup ContextHub in AEM.

Using script reference in AEM ContextHub

While creating audience in AEM contextHub, we see a component called Script Reference. When we drag-n-drop the component, we don't see any scripts by default in the drop down.


Wednesday, 9 January 2019

URL Shortening in AEM

Content pages in AEM start with path /content/. It is best practice to hide /content/site in the URL.

Below configs show how to achieve URL shortening on both AEM server and dispatcher.

Configs on AEM Server:

·         There are many ways to configure the rewrites on publish server. e.g. Resource Resolver, Vanity URLs, Sling mapping.
·         Configuring the Apache Sling Resource Resolver Factory is one of the ways to configure rewrites. This service needs to be configured on the publish server so that if someone hits the publish server directly; we see the correct rules applied there.
Make sure that the publish server has the below configuration applied


Saturday, 5 January 2019

Backend forbids caching, sent: 'Dispatcher: no-cache'

When using dispatcher if we use below code then pages will not be cached in dispatcher. Error in dispatcher.log is "Backend forbids caching, sent: 'Dispatcher: no-cache'"

response.setHeader("Dispatcher", "no-cache");                       
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setDateHeader("Expires", 0);