Email Management and Template Customisation


In this video we are going to look at how FOSUserBundle email templates can be customised, and also how to use Symfony's built in features to work with emails during development.

Configuration of email during development is not specific to FOSUserBundle, so the techniques you see here can be used in any Symfony development environment.

The email template customisations are specific to FOSUserBundle, however.

Before we go further, the majority of our testing for email inside a Symfony application that uses FOSUserBundle will involve visiting the /resetting/request route. When you have visited this route and filled in the form with a valid email address, an email will be sent to the given email address containing details on how to reset your password.

As part of this process, the User entity that relates to this email address will have the $passwordRequestedAt property updated to a DateTime instance of when the password reset was requested.

This will cause you an issue during testing, as once the password_requested_at field inside your database is no longer null, you cannot re-request a password reset for 24 hours. As such, be sure to keep your database client open and set the password_requested_at field back to null before testing the Password Reset workflow.

This is exactly the sort of thing that would be better managed through an automated test :)

However, it is also worthwhile having a secondary method - a simple contact form - on your real web site to allow Users to email you / your helpdesk directly, should something have gone wrong in the process, rather than making a User of your system wait 24 hours to be able to log back in.

If forcing your Users to wait 24 hours is not something you want, you can customise the value in your FOSUserBundle configuration:

# app/config/config.yml

fos_user:
    resetting:
        token_ttl: 86400 # change this value, it is in seconds = 24 hours

Working with Emails in Symfony2

Working with emails inside Symfony is a fairly straightforward process.

As ever, we have lots of different options that we can configure to make it easier for us to work with emails during development.

Because Symfony has the concept of different configuration files for different environments (dev, prod, test, etc), we can very easily have different behaviour for emails depending on whether this is our local development environment, or our production server.

Whilst I can't cover every available option here in this video, I would strongly recommend you check out the Email Cookbook entry as it does a great job of explaining some of the concepts in this video in greater detail.

In this video I make use Swiftmailer to send emails via Gmail. This is great for development:

# app/config/config_dev.yml
swiftmailer:
    transport: gmail
    username:  your_gmail_username
    password:  your_gmail_password

If you do use this method, be sure to follow the Google guide on enabling less secure apps to access your account.

However, perhaps you don't want to actually send any emails during development. Or maybe you are happy to send emails, but you want all your emails to go to your own personal inbox, regardless of who they are really intended for. I use this functionality in the video. Symfony's docs explain it brilliantly.

# app/config/config_dev.yml
swiftmailer:
    disable_delivery:  true
    # delivery_address: you@youremail.com

These options are particularly handy during development.

Disabling email delivery is perfectly fine to do during development as you can use Symfony's awesome Web Debug Toolbar to inspect the contents of the emails that would have been sent.

To do this, you need to enable an additional option inside your web_profiler config:

# app/config/config_dev.yml
web_profiler:
    intercept_redirects: true

Now, whenever an email would have been sent followed by a page redirection, instead of being redirected, you will hit an intermediate page giving you time to examine the Web Debug Toolbar, and inspect the contents of the email(s) that would have been sent.

Again, this is not specific to FOSUserBundle, so you can use this with any Symfony project.

Customising Email Templates in FOSUserBundle

We have already covered how to customise templates inside FOSUserBundle.

The good news is, email template customisations are handled in exactly the same way.

Follow the instructions either in the video, or in the shows notes from the template customisation video, and copy over the email template(s) you wish to customise.

It's easy to spot the twig email templates as they end in .txt.twig, whereas all the HTML / web page templates would end in .html.twig.

If you haven't followed along with the series so far, you may be confused by the contents of the default email templates. They contain translations, rather than the full text content you might expect:

<!-- app/Resources/FOSUserBundle/views/Resetting/email.txt.twig -->
{% trans_default_domain 'FOSUserBundle' %}
{% block subject %}
{% autoescape false %}
{{ 'resetting.email.subject'|trans({'%username%': user.username}) }}
{% endautoescape %}
{% endblock %}
{% block body_text %}
{% autoescape false %}
{{ 'resetting.email.message'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}) }}
{% endautoescape %}
{% endblock %}
{% block body_html %}{% endblock %}

(This example assumes you have copied the templates from the vendors FOSUserBundle folder as per the override instructions in this series)

If you do find the translations confusing then be sure to watch the Translations video, or read the show notes. If translations is still confusing, I have a full tutorial series on Translations in Symfony available here on Code Review Videos.

Of course, if you don't care about translations, feel free to 'hardcode' the text in these templates to whatever you see fit:

<!-- app/Resources/FOSUserBundle/views/Resetting/email.txt.twig -->
{% block subject %}
{% autoescape false %}
Password Reset Email
{% endautoescape %}
{% endblock %}
{% block body_text %}
{% autoescape false %}
You can reset your password by visiting {{ confirmationUrl }}
{% endautoescape %}
{% endblock %}
{% block body_html %}{% endblock %}

Customising Email Senders in FOSUserBundle

A nice feature you may wish to customise inside your own implementation is the ability to send the different types of mail generated by FOSUserBundle from different sender email addresses, and names:

# app/config/config.yml

fos_user:
    from_email:
        address:        generic@yoursite.com
        sender_name:    Generic Sender Name
    registration:
        confirmation:
            from_email: 
                address:        registered@yoursite.com
                sender_name:    Person who handles Registrations 
            enabled:    true # change to false to disable registration email confirmation
    resetting:
        email:
            from_email: 
                address:        noreply@yoursite.com
                sender_name:    No Reply

With this config, newly registered users will receive an email upon successul registration which - by default - will contain a link they must click to confirm and activate their new user account.

This email will be sent with the senders name of 'Person who handles Registrations', with the email address of 'registered@yoursite.com'.

Likewise, password resets will be sent from 'noreply@yoursite.com'.

Any other emails generated by FOSUserBundle will default to using the details of 'Generic Sender Name'.

You could customise this further by specifying alternative email addresses in your config_dev.yml:

# app/config/config_dev.yml

fos_user:
    from_email:
        address:        generic@yoursite.dev
        sender_name:    Generic Sender Name
    registration:
        confirmation:
            from_email: 
                address:        registered@yoursite.dev
                sender_name:    Development Registration
            enabled:    false

This is a contrived example to illustrate a possibility. I would strongly advice you keep your development and production configs as close to matching as possible.

Where To Learn More

FOSUserBundle's documentation has a really useful chapter on email.

An often overlooked part of the documentation is how to send HTML emails in FOSUserBundle.

Also, as mentioned, the way FOSUserBundle works with email in a Symfony application is not specific to FOSUserBundle. All of Symfony's email documentation applies here.

And as ever, if anything is unclear, please feel free to ask a question in the comments section below.

Code For This Course

Get the code for this course.

Episodes