Extending the communities component – Part 2

In one of the earlier post, I talked about extending the communities component. While working on this in my project, I faced another problem. I had a use case to override the toolbar in order to adhere to the custom styles we wanted to apply on the component.

Problem:

  • In comment.hbs, the below line includes the toolbar.hbs. 
{{include this template="toolbar"}}
  • The problem that I faced was that my template changes were not getting picked. I was over-riding the toolbar.hbs, but it was always picking the default OOTB template file.
  • The reason is that whenever we post a comment, it gets saved in the usergenerated content and resource type always points to the OOTB component.community.PNG
  • This resourceType property gets picked up and passed as a parameter to a servlet which resolves the template. You should be able to see the below call in the networks tab of the browser.

http://localhost:4502/services/social/templates?resourceType=social/commons/components/hbs/comments/comment&ext=hbs&selector=toolbar

Solution:

To resolve this issue, we need to tell AEM that it needs to pick our custom resource type rather than OOTB one. There is a configuration for this in the component.

  • Go to the design mode and open the design dialog for comments component.

communities-design-dialog

  • As shown in the above image, you need to specify the path of the custom comment resource type that you want to use in the design dialog. Once you save the changes, you should be able to see your template loading fine.

Hope it helps !! 🙂

Advertisements

Basic URL Rewrite Rules | Hiding the Content Root from URL

One of the requirements in almost every AEM project is to set up the rewrite rules. A typical content URL follows below pattern:

http://<hostname>:<port>/content/mysite/en/mypage.html

It is a best practice not to reveal the repository structure and hide the top level path in the URL i.e. /content/mysite. This blog post will talk about the steps to be made to achieve this on both publish server and dispatcher.

Configuration on AEM Publish 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 on publish server. 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 appliedApache sling resource resolver factory
  • Once you apply this configuration, wait for 5 minutes so that all the services are up and running.

Configuration required on Dispatcher:

  • Set DispatcherUseProcessedURL property to 1. i.e.

<IfModule disp_apache2.c>
DispatcherConfig dispatcher.any
DispatcherLog /var/log/apache2/dispatcher.log
DispatcherLogLevel 3
# DispatcherNoServerHeader 0
DispatcherDeclineRoot 0
DispatcherUseProcessedURL 1
DispatcherPassError 0
# DispatcherKeepAliveTimeout 60
</IfModule>

  • Make sure the mod_rewrite module is loaded in apache.
  • Update the virtual host file and add the below rules in it.

<IfModule mod_rewrite.c>
#Enable this to debug the redirect logs
LogLevel alert rewrite:info
RewriteEngine on

# remove any trailing slash, if it's there.
RewriteRule ^(.+)/$ $1

#Shorten the URL
RewriteRule ^/content/mysite/(.*).html$ $1.html [R,L]
#Map the root folder to the home page
RewriteRule ^/?$ en.html [R,L]

# Ignore requests to "known" AEM root paths, and prefix all others with the proper AEM prefix
RewriteCond %{REQUEST_URI} !^/apps
RewriteCond %{REQUEST_URI} !^/content
RewriteCond %{REQUEST_URI} !^/etc
RewriteCond %{REQUEST_URI} !^/home
RewriteCond %{REQUEST_URI} !^/libs
RewriteCond %{REQUEST_URI} !^/system
RewriteCond %{REQUEST_URI} !^/tmp
RewriteCond %{REQUEST_URI} !^/var
RewriteRule ^/(.*)$ /content/mysite/$1 [PT,L]

</IfModule>

 

Troubleshooting Tips:

  • Restart your apache server every time you make any changes.
  • Enable logging for rewrite module. It will help you to monitor the rules getting applied at each level
  • Check dispatcher logs whether the rules are applied or not and which request is going to publish server.
  • Check if the page invalidation is happening correctly after applying the rewrite rules.
  • Check all the links within the page and navigation bar are correctly shortened.

Hope it helps !! 🙂

 

Communities Component Guide

Adobe has provided one of the most useful feature/utility for developing communities components, known as Communities Component Guide. It is an interactive development tool for the Social Component Framework (SCF). It provides a list of available communities components and complex features built of community components.

Apart from providing the basic information for each component, it lets you experiment with the features as well. You can access the community guides on your instance by following the below URL

http://<server>:<port>/content/community-components/en.html.

The left rail provides the list of the SCF components. Clicking on the component will display the information related to that component. e.g.

  • You should be able to see the title of the component.
  • Clientlibs are very important when it comes to community components. Your component might not behave correctly if the required clientlibs are not included on the page. You should be able to see the required clientlibs for the selected component.
  • It also has the instance of the component on the page so that you can experiment with it. The behavior of the component depends on the instance where you are accessing the guide from. If you are accessing it on the author, then you should be able to see the dialog, can edit the template scripts etc. If you are accessing it on publish then you should be able to experience the features as a site visitor.

It looks like below:

component-guide

Customization:

If you want to do some customizations on the fly, the scg:showIde property must be added to the component page’s content JCR node and set to true.

Lets’ take an example of the comments component:

  1. Go to CRXDE Lite e.g. http://<server>:<port>/crx/de
  2. Select the component’s jcr:content node e.g. /content/community-components/en/comments/jcr:content
  3. Add below property and save.
    • Name  scg:showIde
    • Type   String
    • Value  truecomments-comp
  4. Reload the Comments page in the guide. You should be able to see 3 more tabs.
    http://<server>:<port>/content/community-components/en/comments.html

comments-comp-edit

  • Template Tab: It lets you see the template associated with the component. You can make changes to it, compile and see the results on the screen. Nothing will be saved in the repository.
  • CSS Tab: It lets you modify the CSS and see the changes on the component placed on the page.
  • Data Tab: To modify the.social.json associated with the component.

If you are a beginner and trying your hands with AEM communities, this will surely help you.

Hope it helps !! 🙂

 

How does Sightly template work?

In one of the earlier post, I explained how to create a multifield component in sightly and using sling models. In this post, I’ll talk about how to create and use “sightly templates” in your component. Templating is a powerful feature introduced in Sightly, which helps in keeping your code clean and makes it more reusable. Identify the repetitive code blocks in your markup, create a template and reuse it wherever it is required.

Let’s see how to create a template and how to call it:

  1. A basic template can be created by below snippet. Each template requires an identifier. For Instance, in the below snippet I have created a template in a file “message.html” with the name “message1”.
     <template data-sly-template.message1>
    <h2> This is template 1</h2>
    </template> 

    Now that the template is created, we can call using the data-sly-call and data-sly-use it as follows and use it in our code.

    <div data-sly-use.messageRenderer="message.html">
    <sly data-sly-call="${messageRenderer.message1}"/>
    </div>
    
  2. We have seen the example to create a basic template, now we’ll see how to pass parameters to our template.
    <template data-sly-template.message2="${@ message}">
    Message is
    <h2> ${message}</h2>
    </template> 

    To call this template in our code, we’ll have to use the below snippet.

    <sly data-sly-test="${properties.text}"
    data-sly-call="${messageRenderer.message2 @ message=properties.text}"/>

    The entire HTML will look like:template1If there are multiple parameters, pass it as comma separated values.

    <sly data-sly-call="${messageRenderer.message2 @ param1=param1,param2=param2 }"/>

Find the complete code in the Github repository.

Hope it helps !! 🙂

Multifield Component in Sightly with Sling Models

Starting AEM 6.0, new templating language Sightly now known as HTL is introduced. It offers highly productive enterprise-level web framework that increases security and allows HTML developers without Java knowledge to better participate in AEM projects.

Adobe recommends any new components to be developed using Sightly. Speaking of components, one of the vital components of any AEM application is a multifield component. More often than not, you will come across a requirement where you would have to create a multifield component, be it a social link component or a custom carousel component etc.  This post will talk about creating a multifield component in Sightly using Sling Models.

Infrastructure Used:

  • AEM Instance : 6.2
  • OS: Windows 10

Follow the below Steps to create the multifield component:

  1. Firstly Create a sample AEM project using the maven archetype 10.
  2. Create a new Sightly component. You can take reference from this article. Create the structure like below for multifield componentmultifield (I would be sharing the complete code, don’t worry).
  3. The links get saved in the below format.links
  4. Write a Sling Model to parse these links. Read my earlier post about the issue with sling models in 6.2.
</pre>
<pre>@Model(adaptables = Resource.class)
public class DemoMultiFieldModel {

    Logger logger = LoggerFactory.getLogger(DemoMultiFieldModel.class);

    @Inject
    @Named("links")
    private String[] links;

    private List<Link> list;

    @PostConstruct
    protected void init() throws JSONException {
        logger.info("links" + links);
        this.list = new ArrayList<Link>();
        for (String linkString : links) {
            JSONObject jsonObject = new JSONObject(linkString);
            logger.info("json object is " + jsonObject);
            list.add(new Link(jsonObject.getString("linktext"), jsonObject.getString("linkURL")));
        }
        logger.info("linkList is" + list);
    }

    public List<Link> getList() {
        return list;
    }
}</pre>
<pre>
  1.  Now, invoke this model in your Sightly file.
Demo MultifieldPanel component
<p data-sly-test="${properties.heading}"> ${properties.heading}</p>
<p data-sly-test="${properties.desc}"> ${properties.desc}</p>

<div data-sly-use.linkModel="aem.bootstrap.core.models.DemoMultiFieldModel">
${linkModel.message}
<div data-sly-test="${linkModel.list}" data-sly-list.list="${linkModel.list}">
<b>page:</b> ${list.linktext}
<b>path:</b> ${list.linkURL}
</div>
</div>
  1. You also have to add the nested-multifield.js since nested multifield is not supported OOTB. You can find it in the code repository below.

If everything is fine, your sightly component should look like below:

sightly page

You can clone the code from here.

References :

https://helpx.adobe.com/experience-manager/using/creating-sightly-component.html

https://sling.apache.org/documentation/bundles/models.html

https://helpx.adobe.com/experience-manager/using/domparser.html

Hope it helps !! 🙂

Managing Community Users in AEM | Tunnel Service

The trend of having the interactive websites is more common these days. Users can interact through forums, by posting comments, by participating in quizzes etc. AEM Communities provides a rich framework to have such interactive websites. Users can either come from LDAP/AEM or you can allow Social logins as well. But, with this increases the need of managing such users in a highly interactive website.

Recently, we encountered a serious issue in one of our projects.

Problem/Use Case: 

Usually, the logins happen on a Publish instance which makes the users being created on the Publish instance itself. Now, in an interactive community site, users are added to Community Groups so that they can interact. Now, there are two options to add these users to the groups:

  1. Have some trusted users who can use the useradmin console and assign the users to the particular Community groups.Users who gets assigned to such community groups are called members on the publish instance.
  2. Have the same users on author instance, add them to appropriate Community groups and activate it.

Now, the first option imposes some of the security risks, so we were using the 2nd option. But lately, we realized that as the number of users increases the performance of author instance starts degrading.

Solution:

Adobe has provided a way to have these users in the publish instance and yet manage it from the author instance. You can use the tunnel service to have the publish users available in the author instance. Follow the below steps:

  1. Go to Configuration Manager on author instance and look for the AEM Communities Publish Tunnel Service  and click on enable. This service needs to be enabled on the author instance only.tunnel service
  2. Now, Go to the members console on author instance. You should be able to see all the users now. members console
  3. Clicking on create button will allow you to add a new member into the publish instance and assign it to particular Community Site and Community Groups.
  4. Similarly, Groups console will allow you to manage the Community Groups.

Troubleshooting:

  1. Make sure both the author and publish instance will have the same configuration i.e. Both should be on AEM 6.1 (SP1+FP4) or above. In FP3, tunnel service does not allow the management of members from author instance. This feature was added in FP4.
  2. Make sure the bundles are up and running in both the instances. Otherwise,you will not be able to see any users in the members console.
  3. If you are not able to see the default users, make sure you are not running on nosamplecontent runmode.

References:

https://docs.adobe.com/docs/en/aem/6-1/administer/communities/users.html

https://docs.adobe.com/docs/en/aem/6-1/administer/communities/consoles/members.html

Hope it helps !! 🙂

Automating Content Migration Using Talend

Redevelopment of a website is often triggered because of three major factors:

  • The current website is built on the technology stack which is now obsolete.
  • Redesigning/Revamping the existing website, either to address the weaknesses in the current system or to add significant features.
  • Switching to a new technology platform, such as a new Content Management System (say AEM).

Often these factors are coupled together, selecting the new technology platform combined with redesigning the existing site. Identification of the new technology platform is a difficult task and subject to various factors like budget, feasibility, stability of the new technology stack, maintenance support, time to market etc. No matter what that choice is, more often than not gives birth to migration projects. An organization that has thousands of Pages, Articles, Assets etc would want to retain that data rather than creating everything from scratch. Migration has a very wide scope, but this blog post will talk about Content Migration.

Content Migration is a process of migrating the existing Digital Media of an organization to the new System. Being involved in various Content Migration Projects, I can say that this is not a simple process.

A change in technology platforms makes the migration challenging, as does a major restructure or redesign of the site.

Content Migration can be achieved by either of the following two ways or sometimes combined:

  1. Manual: Ctrl+C and Ctrl+V are the favorite keyboard shortcuts for every developer. The manual way is always the easiest yet the most painful one. If it is about a few pages, you might want to copy the content from the old site and paste into the new publishing tool. But, if the old system contains thousands of pages, would you want to follow that route? Maybe you can hire a team of content authors who’ll do the job for you. But a manual process is error-prone.
  2. Automated: Option of automating the entire process of migration is clearly an appealing one. Using some tool/methodology where you can define the rules for the migration process. This requires little or no manual effort. Talend Open Studio (ETL tool) is one such tool which can be used to automate the content migration process . You can refer Talend Open Studio Reference Guide for better understanding of the tool.

There are three basic requirements for migration:

  1. The input export of the existing content. It can be in any form e.g. Delimited Text file, XML file etc depending on the existing system.
  2. The output format i.e. What should be the end result of the migration process? Which data from the existing system should map to the new system (AEM in our case)? You should be clear with all the mapping and transformation rules specific to the new system. As we are dealing with migration to AEM, then we need to define the mappings between the existing content and AEM components. For instance, if the input extract received is an XML file then you would have to define the mappings among XML tags and the properties of an AEM component.
  3. Loading Mechanism which defines how the content gets loaded into the target System. This is a very important part as whole migration process will be designed based on the method of load. We’ve chosen the approach of creating a valid CQ Package which can be installed from CRX package manager. One of the major advantages of using this approach is that we can easily rollback and uninstall the package.

A basic migration job created using Talend looks like as follows:

main job.png

Each block in the above picture is a component, tRunJob in this case which calls another sub-job. The connectors between two such blocks define the transition i.e. how and when do we want the next block to be executed. In this case, these transitions are called as triggers.

This main job consists of four sub-jobs. Purpose of each sub-job is explained below:

  1. Pre-migration Cleanup: This job reads the input content (say XML) and breaks it into smaller manageable chunks (multiple XML files) which can be worked upon individually. The job can be modified to handle scenarios like Internal URL mapping, resolving the character encoding issues, define any tag mapping rules etc.
  2. Extraction & Transformation: This job reads the XMLs created in the previous step one by one, transforms it to AEM specific .content.xml schema and stores it under the required jcr_root hierarchy on the file system.
  3. Post Migration Cleanup:  This job is required if there are any post-migration cleanups that need to be done.
  4. Packaging: This is the final step of migration which creates the archive of the pages migrated in the above steps. Keep in mind that the package needs to be AEM compatible i.e. it should contain jcr_root & META_INF folder and associated metadata properties as per AEM packaging standard.

Content Migration is an important activity in redevelopment of a website and it needs proper planning. While you can automate the migration process but it will always require human eyes to approve the migrated content.

Hope this helps !! 🙂