Your browser (Internet Explorer 6) is out of date. It has known security flaws and may not display all features of this and other websites. Learn how to update your browser.
X

Archive for November, 2015

Zia Lightning Talks: Alfresco Email Templates

Zia conducts monthly, internal lightning talk sessions. These short, five-minutes presentations cover topics important to Zia, our partners, and the industry. We’ve decided to start sharing some of these useful presentations with you. This post covers the talk presented by Lucas Patingre, ECM Architect at Zia Consulting.

Despite some companies trying to shut down internal emails, they are still frequently used as a notification tool. Right out-of-the box, Alfresco gives us the ability to send inline emails—written directly in the code—in both html and text formats, or to send the emails based on templates.

Benefits of Alfresco Templates

  • Separation of the view
    • Separating the presentation layer from the code makes it easier to work on the email structure or the dynamic content independently.
    • In the end, this will allow us to write and maintain more complex emais.
  • Localization
    • Alfresco supports multiple languages which manifests at several levels. The most obvious is the UI where all text is encapsulated within localized properties files to render based on user preferences.
    • For email templates, we can create one template file per language we want to support and then choose the right one at the time we send the email.
  • Edit online
    • The email templates are stored in the repository making it simple for an administrator to edit them without creating a new build of a customization.

How-To Use Alfresco Templates

  • Calling the action
    • Instead of passing raw text to the email action, you will pass the reference to a template node and a parameter map with the data to inject.

Before:

Action mail = actionService.createAction(MailActionExecuter.NAME);
mail.setParameterValue(MailActionExecuter.PARAM_SUBJECT, "Inline email subject");
mail.setParameterValue(MailActionExecuter.PARAM_TEXT, "Inline email body");

After:

Map<String, Object> model = new HashMap<String, Object>();
Action mail = actionService.createAction(MailActionExecuter.NAME);
mail.setParameterValue(MailActionExecuter.PARAM_SUBJECT, "Templated email subject");
mail.setParameterValue(MailActionExecuter.PARAM_TEMPLATE, getEmailTemplate());
mail.setParameterValue(MailActionExecuter.PARAM_TEMPLATE_MODEL, (Serializable) model);
  • Bootstrapping the email templates
    • While not mandatory, it’s better to bootstrap the templates to the repository instead of uploading them manually. You should end up with one template per language you want to support, similar to this:

Example

Note: The configuration used to bootstrap the templates is out of the scope of this blog post. You can find reliable resources online on how to bootstrap using the ImporterModuleComponent.

  • Localized email template fetching: getLocalizedSibling
      • The FileFolderService has an interesting method called getLocalizedSibling that can retrieve a localized (using the server’s locale) version of the template.
private NodeRef getEmailTemplate() {
    try {
        List<NodeRef> nodeRefs = searchService.selectNodes(
                nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE), EMAIL_TEMPLATE_XPATH, null,
                nameSpaceService, false);
        if (nodeRefs.size() != 1) {
            logger.error("Cannot find the saved search notification email template: " + EMAIL_TEMPLATE_XPATH);
            return null;
        }
        return fileFolderService.getLocalizedSibling(nodeRefs.get(0));
    } catch (SearcherException e) {
        logger.error("Cannot find the saved search notification email template: " + EMAIL_TEMPLATE_XPATH, e);
    }
    return null;
}

Capabilities of FTL Templates

  • Basic variable injection
    • This is extracted from the default “Following” email template in Alfresco
<html>
    <#assign followerFullName>${followerFirstName} ${followerLastName}</#assign>
    <body>
        <table>
            <tr>
                <td>
                    <img src="${shareUrl}/res/components/images/help-people-bw-64.png" />
                </td>
                <td>
                    <div>${(followerFullName?trim)?html} is now following you.</div>
                    <div><#if followerJobTitle??>${followerJobTitle?html}<br/></#if></div>
                </td>
            </tr>
        </table>
    </body>
</html>
  • Freemarker logic
    • This is extracted from the default “Activities” email template in Alfresco. As activities can be one of several kinds and we want to format the notification differently for each kind, it requires more ftl logic. I have remove much of the actual display work to mainly keep the logic structures.
<div>
    <#if activities?exists && activities?size > 0>
        <#list activities as activity>
            <#if activity.siteNetwork??>
                <#assign firstVar="Something">
                <#assign otherVar=false>
                <#switch activity.activityType>
                    <#case "org.alfresco.site.user-joined">
                    <#case "org.alfresco.site.user-left">
                        <#assign firstVar="Something else">
                    <#break>
                    <#case "org.alfresco.site.user-role-changed">
                        <#assign otherVar=true>
                    <#default>
                </#switch>
                <div class="activity">
                    <#if otherVar>${firstVar}<#else>Not var</#if>
                </div>
            </#if>
        </#list>
    </#if>
</div>
  • Handle nodes
    • Another useful is the ability to fetch nodes and access their different properties. To use this, you will need to inject “companyhome” in your email template.
<table>
    <tr>
        <th>Modified date</th>
        <th>Modifier</th>
        <th>File</th>
    </tr>
    <#list savedSearch.getNewResults() as savedSearchResult>
        <#assign savedSearchResultNode=companyhome.nodeByReference[savedSearchResult.toString()]>
        <tr>
            <td>${savedSearchResultNode.properties.modified?date}</td>
            <td><a href="${shareUrl}/page/user/${savedSearchResultNode.properties.modifier?html}/profile">${savedSearchResultNode.properties.modifier}</a></td>
            <td><a href="${viewUrl}${savedSearchResultNode.properties['sys:node-uuid']}">${savedSearchResultNode.properties.name}</a></td>
        </tr>
    </#list>
</table>

From this, you can see the benefits of utilizing these templates to create a more streamlined deployment of your email communications. If you have any questions on how to best implement this approach, please contact us today.