# Insert a dynamic text in an email for Joomla

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 extension, for example a user birthday, purchased product, booked event, etc...

Here is an example with a user field:

<figure><img src="https://963725040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_D4iy53WFAtKVs3BPA-3566562695%2Fuploads%2FFST0fNsTzPxme7EMSKEG%2Fcustom%20addon%20dtext%20example.png?alt=media&#x26;token=03d52f55-2448-43f7-a7e8-6df4906b43b7" alt="" width="375"><figcaption></figcaption></figure>

<figure><img src="https://963725040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_D4iy53WFAtKVs3BPA-3566562695%2Fuploads%2FlW5uN5zwFSnF6aLJ4WrP%2Fcustom%20addon%20dtext%20example%20result.png?alt=media&#x26;token=f7f52e47-d39b-48de-89a4-a2568ef60904" alt="" width="281"><figcaption></figcaption></figure>

For this step by step guide, we will take two simple examples and make an add-on allowing us to insert:

* the current month name
* the user account name

### Base file

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

{% content-ref url="" %}
[](https://docs.acymailing.com/developers/making-a-custom-add-on)
{% endcontent-ref %}

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

{% code lineNumbers="true" %}

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

    $this->pluginDescription->name = 'Example add-on';
}

```

{% endcode %}

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:

{% code lineNumbers="true" %}

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

{% endcode %}

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:

{% code lineNumbers="true" %}

```php
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;
}
```

{% endcode %}

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 main file should look like this:

{% code lineNumbers="true" %}

```php
<?php

use AcyMailing\Core\AcymPlugin;

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

        $this->pluginDescription->name = 'Example add-on';
    }

    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;
    }
}

```

{% endcode %}

Your insertion options should already be visible in the AcyMailing editor:

<figure><img src="https://963725040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_D4iy53WFAtKVs3BPA-3566562695%2Fuploads%2FXMtPc48YxLVjQYLQ0kkl%2Fcustom%20addon%20dtext%20example%20insertion%20options.png?alt=media&#x26;token=3814a935-1f39-47d6-b994-602c9aa8eddf" alt="" width="375"><figcaption></figcaption></figure>

### 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:

{% code lineNumbers="true" %}

```php
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);
}
```

{% endcode %}

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:

<figure><img src="https://963725040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_D4iy53WFAtKVs3BPA-3566562695%2Fuploads%2Fl55TK9dAygowjI3AzXuf%2Fcustom%20addon%20dtext%20example%20month.png?alt=media&#x26;token=8fcb0f6b-cb70-44a7-963b-f957a9d51593" alt="" width="235"><figcaption></figcaption></figure>

### 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:

{% code lineNumbers="true" %}

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

    $userAccount = null;

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

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

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

        $contentToInsert = '';

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

        $tags[$i] = $contentToInsert;
    }

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

{% endcode %}

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 user account information ahead, to avoid doing it in the loop.

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

<figure><img src="https://963725040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_D4iy53WFAtKVs3BPA-3566562695%2Fuploads%2FnNLz42Ko7E3NSa04Ih0E%2Fcustom%20addon%20dtext%20example%20name.png?alt=media&#x26;token=4cbb55cb-993c-4638-91cb-474d69c6f266" alt="" width="156"><figcaption></figcaption></figure>

Your entire code should look like this:

{% code lineNumbers="true" %}

```php
<?php

use AcyMailing\Core\AcymPlugin;

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

        $this->pluginDescription->name = 'Example add-on';
    }

    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;
            }

            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;
        }
    
        $userAccount = null;
    
        if (!empty($user->cms_id)) {
            // We store the user account id in cms_id when it exists
            $userAccount = acym_loadObject('SELECT * FROM #__users WHERE id = '.intval($user->cms_id));
        }
    
        if (empty($userAccount)) {
            // We get the  also try to find the Joomla user by its email address
            $userAccount = acym_loadObject('SELECT * FROM #__users WHERE `email` = '.acym_escapeDB($user->email));
        }
    
        $tags = [];
        foreach ($extractedTags as $i => $oneTag) {
            if (isset($tags[$i])) {
                continue;
            }
    
            $contentToInsert = '';
    
            if ($oneTag->id === 'name' && !empty($userAccount)) {
                $contentToInsert = $userAccount->name;
            }
    
            $tags[$i] = $contentToInsert;
        }
    
        $this->pluginHelper->replaceTags($email, $tags);
    }
}

```

{% endcode %}
