1

Looking to build a hybrid news service that publishes to a website but also sends an entry to a mailing list. Has anyone done anything similar?

3

You would need to attach such functionality to EVENT_AFTER_SAVE event in the custom php module.

The module can be built using plugin factory website. For attaching functionality to the event, you don't need to select any additional components.

https://pluginfactory.io/

You can find useful information about modules here:

https://nystudio107.com/blog/enhancing-a-craft-cms-3-website-with-a-custom-module

Add these statements to use section in main module class:

use yii\base\Event;
use craft\elements\Entry;
use craft\events\ModelEvent;
use craft\helpers\ElementHelper;

Now you need to attach functionality to the event - add this code to modules main class, in init() method:

Event::on(
    Entry::class,
    Entry::EVENT_AFTER_SAVE,
    function(ModelEvent $event) {

        // react only to entries from this section:
        $section_id = 1;

        // entry data
        $entry = $event->sender;


        // if it is not a draft
        if (ElementHelper::isDraftOrRevision($entry)) {
            return;
        }

        // if entry has specific section
        if($entry->sectionId != $section_id){
            return;
        }

});

This code will run when you save entry in a specific section. Now, you need to give ourselves some control.

We will make our code run only when we check a specific field in our entry. Create lightswitch field and add it to entry field layout. Thanks to the code below, an email will be sent only when entry is saved and lightswitch is checked. Lightswitch will be automatically de-checked after saving. Just remember that lightswitch field needs to be disabled by default to keep you from accidentally sending email when you save entry first time.

$lightswitchHandle = 'someField';
if($entry->getFieldValue($lightswitchHandle) !== true){
    return;
}

$entry->setFieldValue($lightswitchHandle, false);
Craft::$app->elements->saveElement($entry);  

Now we need to compose our email:

// compose email from entry content
$email_template = 'path_to_email_template.twig';
Craft::$app->getView()->setTemplateMode(\craft\web\View::TEMPLATE_MODE_SITE);
$email_html = Craft::$app->view->renderTemplate(
    $email_template,
    [   
        'entry' => $entry,
    ]
);
Craft::$app->getView()->setTemplateMode(\craft\web\View::TEMPLATE_MODE_CP);

This code will inject the contents of entry as entry variable into Twig template path_to_email_template.twig placed in templates directory and render email HTML. I suggest giving your email some nice base template - here are good examples:

https://postmarkapp.com/transactional-email-templates

Now what you will do with such email, is up to you. You could potentially send this email manually using Craft mailer class:

$email_recepients = ['bob@email.com', 'mike@email.com'];
$email_subject = 'interesting content inside!';

Craft::$app
->getMailer()
->compose()
->setTo($email_recepients)
->setSubject($email_subject)
->setHtmlBody($email_html)
->send();

Just try to avoid sending emails using server built-in sendmail functionality, this can lead to your ip/domain being marked as spam-sending. It's good to use some middleman services like mailgun.

https://www.mailgun.com/smtp/

You can attach Craft to mailgun SMTP using the application configuration file:

https://docs.craftcms.com/v3/config/app.html#mailer-component

If you want to test how your emails behave, you can use a mock SMTP server like mailtrap:

http://craftsnippets.com/articles/testing-and-debugging-emails-sent-by-craft-cms-using-mailtrap

An alternative to using SMTP might be mailchimp service or something like that - in that case, instead of using Craft mailer, you would use some dedicated PHP library to send email to service API.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.