Insert a dynamic text in an email for WordPress

This step by step guide shows you how to develop your own plugin, allowing you to insert user-based data or data common to all receivers in your emails.

Sometimes it can be useful to insert texts based on the receiver of a campaign, most commonly their name for example to have a less generic email.

You may want to insert data stored in an other plugin, for example a user birthday, purchased product, booked event, etc...

Here is an example with a user field:

For this step by step guide, we will take two simple examples and make a plugin allowing us to insert:

  • the current month name

  • the WordPress user name

Base files

Before continuing, make sure you created a custom add-on by following this guide:

Making a custom add-on

In the file plugin.php, add the following method to your class:

public function __construct()
{
    parent::__construct();

    $this->pluginDescription->name = 'Example add-on';
    $this->pluginDescription->category = 'Anything';
    $this->pluginDescription->description = '- Insert month and user name in emails';
}

The name set on line 5 will be shown as a new "Dynamic text type"

Define the insertion options

For your integration to be visible in the editor, you will need to add the following method to your plugin.php file:

public function dynamicText($mailId)
{
    return $this->pluginDescription;
}

If you want your integration to only be visible on some types of emails for example, you can use the $mailId variable to test it and return nothing to hide it.

To define the insertion options that will be shown in the "Content to insert" part, you will need to add the following method:

public function textPopup()
{
    $insertionOptions = '<div class="grid-x acym__popup__listing">';
    $insertionOptions .= '<div onclick="setTag(\'{'.$this->name.':month}\', jQuery(this));" class="cell acym__row__no-listing acym__listing__row__popup">Current month</div>';
    $insertionOptions .= '<div onclick="setTag(\'{'.$this->name.':name}\', jQuery(this));" class="cell acym__row__no-listing acym__listing__row__popup">User name</div>';
    $insertionOptions .= '</div>';

    echo $insertionOptions;
}

This method needs to display your insertion options using HTML. It can be however you want, the most important thing is to call the JavaScript function "setTag" with a shortcode containing a unique value for what we want to insert (in this example, "month" and "name").

At this point, your plugin.php file should look like this:

<?php

use AcyMailing\Libraries\acymPlugin;

class plgAcymExampleaddon extends acymPlugin
{
    public function __construct()
    {
        parent::__construct();

        $this->pluginDescription->name = 'Example add-on';
        $this->pluginDescription->category = 'Anything';
        $this->pluginDescription->description = '- Insert month and user name in emails';
    }

    public function dynamicText($mailId)
    {
        return $this->pluginDescription;
    }

    public function textPopup()
    {
        $insertionOptions = '<div class="grid-x acym__popup__listing">';
        $insertionOptions .= '<div onclick="setTag(\'{'.$this->name.':month}\', jQuery(this));" class="cell acym__row__no-listing acym__listing__row__popup">Current month</div>';
        $insertionOptions .= '<div onclick="setTag(\'{'.$this->name.':name}\', jQuery(this));" class="cell acym__row__no-listing acym__listing__row__popup">User name</div>';
        $insertionOptions .= '</div>';
    
        echo $insertionOptions;
    }
}

If you activate your plugin, your insertion options should already be visible in the AcyMailing editor:

Dynamically insert a content common to all receivers

In this example, we chose to insert the current month. Since it will be the same for all receivers, we can use the method "replaceContent" which uses less resources:

public function replaceContent(&$email, $send = true)
{
    $extractedTags = $this->pluginHelper->extractTags($email, $this->name);
    if (empty($extractedTags)) {
        return;
    }

    $tags = [];
    foreach ($extractedTags as $i => $oneTag) {
        if (isset($tags[$i])) {
            continue;
        }
        
        // Your code here
        if ($oneTag->id === 'month') {
            $tags[$i] = date('F');
        }
    }

    $this->pluginHelper->replaceTags($email, $tags);
}

In this example, you just need to modify the loop content near line 14. Note that the $email parameter contains the current email information, and the $send parameter tells you if the email is about to be sent (true) or if we just want to display a preview (false).

You should always set a new value to $tags[$i] to replace the shortcode in the sent email.

At this point, inserting the month should work and a preview should be visible in the blue label. Inserting the user name should display the shortcode instead since we haven't added the code to replace it yet:

Dynamically insert a content based on the receiver

To insert a text based on the receiver, we need to use the method "replaceUserInformation" that is called for every recipient. The current email and the AcyMailing user objects are passed to help you find the data you want to insert:

public function replaceUserInformation(&$email, &$user, $send = true)
{
    $extractedTags = $this->pluginHelper->extractTags($email, $this->name);
    if (empty($extractedTags)) {
        return;
    }

    $wordpressUser = null;

    if (!empty($user->cms_id)) {
        // We store the WordPress user id in cms_id when it exists
        $wordpressUser = acym_loadObject('SELECT * FROM #__users WHERE ID = '.intval($user->cms_id));
    }

    if (empty($wordpressUser)) {
        // We could also try to find the WordPress user by its email address
        $wordpressUser = acym_loadObject('SELECT * FROM #__users WHERE `user_email` = '.acym_escapeDB($user->email));
    }

    $tags = [];
    foreach ($extractedTags as $i => $oneTag) {
        if (isset($tags[$i])) {
            continue;
        }

        $contentToInsert = '';

        if ($oneTag->id === 'name' && !empty($wordpressUser)) {
            $contentToInsert = $wordpressUser->display_name;
        }

        $tags[$i] = $contentToInsert;
    }

    $this->pluginHelper->replaceTags($email, $tags);
}

You should only need to modify lines 28 to 30 and set the value that should be inserted into the variable $contentToInsert.

In this example, lines 8 to 18 we try to get the WordPress user information ahead, to avoid doing it in the loop.

At this point your integration is ready and the WordPress user name should be inserted correctly:

The entire code for plugin.php should look like this:

<?php

use AcyMailing\Libraries\acymPlugin;

class plgAcymExampleaddon extends acymPlugin
{
    public function __construct()
    {
        parent::__construct();

        $this->pluginDescription->name = 'Example add-on';
        $this->pluginDescription->category = 'Anything';
        $this->pluginDescription->description = '- Insert month and user name in emails';
    }

    public function dynamicText($mailId)
    {
        return $this->pluginDescription;
    }

    public function textPopup()
    {
        $insertionOptions = '<div class="grid-x acym__popup__listing">';
        $insertionOptions .= '<div onclick="setTag(\'{'.$this->name.':month}\', jQuery(this));" class="cell acym__row__no-listing acym__listing__row__popup">Current month</div>';
        $insertionOptions .= '<div onclick="setTag(\'{'.$this->name.':name}\', jQuery(this));" class="cell acym__row__no-listing acym__listing__row__popup">User name</div>';
        $insertionOptions .= '</div>';

        echo $insertionOptions;
    }

    public function replaceContent(&$email, $send = true)
    {
        $extractedTags = $this->pluginHelper->extractTags($email, $this->name);
        if (empty($extractedTags)) {
            return;
        }

        $tags = [];
        foreach ($extractedTags as $i => $oneTag) {
            if (isset($tags[$i])) {
                continue;
            }

            // Your code here
            if ($oneTag->id === 'month') {
                $tags[$i] = date('F');
            }
        }

        $this->pluginHelper->replaceTags($email, $tags);
    }

    public function replaceUserInformation(&$email, &$user, $send = true)
    {
        $extractedTags = $this->pluginHelper->extractTags($email, $this->name);
        if (empty($extractedTags)) {
            return;
        }

        $wordpressUser = null;

        if (!empty($user->cms_id)) {
            // We store the WordPress user id in cms_id when it exists
            $wordpressUser = acym_loadObject('SELECT * FROM #__users WHERE ID = '.intval($user->cms_id));
        }

        if (empty($wordpressUser)) {
            // We could also try to find the WordPress user by its email address
            $wordpressUser = acym_loadObject('SELECT * FROM #__users WHERE `user_email` = '.acym_escapeDB($user->email));
        }

        $tags = [];
        foreach ($extractedTags as $i => $oneTag) {
            if (isset($tags[$i])) {
                continue;
            }

            $contentToInsert = '';

            if ($oneTag->id === 'name' && !empty($wordpressUser)) {
                $contentToInsert = $wordpressUser->display_name;
            }

            $tags[$i] = $contentToInsert;
        }

        $this->pluginHelper->replaceTags($email, $tags);
    }
}

Last updated