Extend existing selection with selection_add in Odoo 10

In this tutorial I will teach you how to extend an existing selection through code in Odoo 10. You will learn how to extend the selection (without overriding the existing keys) and only adding new keys with the “selection_add” parameter.
In this tutorial I will extend the existing selection for an employee where the gender is set. After this toturial you will be able to add new keys to a selection.

1. Adding the correct dependencies

Alright let us start right away! First of all you will need to add a dependency to the module from which you want to extend the selection. In this tutorial I will need the “hr” module and I’ll add in the “contacts” module too because you’ll want to see the contacts anyway. Open up your __manifest__.py and add in the dependencies you need:

2. Inheriting the model

Now create a new Python file that inherits the model on which you want to extend an existing selection. In my example I’ll need to inherit ‘hr.employee’ as the field ‘gender’ is on this model:
Gender field on hr.employee
Your code should now look like this:

3. Extending the selection

Finally (or should I say already?) you can extend the field and add the new options you’d like. Inheriting the existing field is as simple as calling it with the same name again. Then just use the “selection_add” key to insert new options. Your code should be looking like this:

So what does this code do? Rather then having to give all key values again you can simply add only the new values you’d like. Odoo will automatically add these values to the selection without modifying anything to the existing keys. As a result this is the cleanest way to extend selections and prevents you from reassigning values every time. Your final code should now look like this:

After you’ve installed this custom code you’ll see that the new value is added because of this code:
Result selection field

4. Conclusion

Extending selections in Odoo has become very easy due to the “selection_add” parameter. It allows you to extend selections without having to override existing keys and removes some complexity and margin for errors.
Do you want to try the demo code and see the source code of this tutorial? You can view it on my Github account.
Has this tutorial helped you, do you have any feedback or questions? Post away!


Creating webpages and controllers in Odoo 10

In this tutorial I will teach you how to create new webpages and controllers through code in Odoo 10. You will learn how to create new webpages (in XML), how to create controllers and how to use controllers to open specific webpages. After following this tutorial you will be able to create your own webpages and controllers in Odoo.
In this example I will create a webpage with a button. The button click will call a controller function and this controller will redirect you to another webpage. On this page we will show the details of all the companies in your Odoo:
Example result

1. Creating the controller structure

Before you can create (and call) a webpage you need to make a controller. This controller will tell Odoo which URL links to which webpage. Open up your module and create a folder ‘controllers’ if you don’t have one yet. After creating this folder make an __init__ file and add the followig line of code in it:

Now that you have an import that is directly loaded by Odoo (thanks to the __init.py__) you should create a new Python file. Name this new file ‘example.py’, which will be the controller. As a result your folder structure should be looking like this:
Folder structure

1.1 Creating the controller

Let us create our first controller now! Just have a look at this code:

So, what does this tell you? In order to let an user navigate to a specific page you will need an @http.route. This @http.route will tell Odoo that we want to link the url ‘/example’ to a specific webpage. Inside the @http.route you will see four variables. Let me explain them one by one:

  • ‘/example’: Because Odoo needs to know which URL links to what (XML) template you’ll need to provide the URL first. In this example it means that http://localhost/example would call this @http.route
  • type=’http’: This will let Odoo know that your page is running in HTTP.
  • auth=’public’: Tells Odoo who can view the page.
    You can choose between ‘public’, ‘user’ and ‘none’. If you choose ‘public’ anybody can view the page. When you choose ‘user’ only logged in people can view this page and if  you choose ‘none’ there will be no facilities to access the database or any configuration. For more information see the official documentation
  • website=True: Tells Odoo that is has to link to a webpage and that it is not just a Python function.

After calling @http.route you will need to give the Python function a name, in this example render_example_page(self). Notice that self is also passed along in functions in the front-end of Odoo, just like in the backend.

1.2 Returning the controller function

Finally, you need to return the function. Because the function needs to know which XML record needs to be called we pass it along like this:

http.request.render will call the view renderer from the Odoo framework. within the brackets “()” you have to specify the module_name.page_name. In this case my module is named ‘create_webpage_demo’ and I will create a webpage with the technical name ‘page_name’. In this http.request.render you’ll also see {}. Why is this there? You can pass variables and data along in this dictionary to the website. Further in this tutorial I will show an example about how to do this, so don’t worry about it yet.

2. Creating the webpage

Close the Python file, go into the ‘views’ folder and create a new XML file named ‘example_webpage.xml’. Add this XML file in your manifest.py first:

Now go back to your example_webpage.xml file and create a new XML record. You’ll notice that creating a new webpage is just as easy as creating an Odoo view. Have a look at this code first and then add it in your module:

Does this make sense to you? Let me explain it step by step. The record starts with a template id, which is identical to creating views in Odoo. Why did I name this example_page though? Because in the controller we did this: return http.request.render(‘create_webpage_demo.example_page‘, {}). As a result Odoo will now know that the controller needs to render the XML view that we’re now coding. Did you notice the page=”True” key too? Since Odoo needs to know if it is a webpage or not there is a key ‘page’ added in Odoo. By settings this key to true Odoo knows it’ll become a webpage. Next, we have the following line:

Because of this Odoo knows that it has to take the default webpage lay-out and needs to apply it to this XML record. The next line has some noteworthy features. The div class oe_structure will add the feature to use building blocks within Odoo, which is otherwise not possible. As a result other people, that use your Odoo that do not have technical knowledge, will be able to use building blocks to style the webpages. As for the rest of the code? You could basically add what you want here. Because Odoo implements bootstrap, less and font awesome you can use a lot of features out of the box!

2.1 Saving and showing the webpage

Finally, save this page, update your module and open your Odoo. In the website go to /example and you’ll see the following result:
Example page
Do you see that button? In the XML record that we just created I added the following line of code:

I’ve added a t-attf-href in this line with a reason, but why? Because the Odoo framework will be triggered the moment that you click on this button. Odoo can interpret this code and knows that you want to open the page /example/detail.
So, let us continue and let us create another function in the controller to handle this.

2.2 Second function in controller

Open up the Python file ‘example.py’ again and let us create a second function, just like we did with the first. There will be just one addition to the code, we’ll also pass data to the next webpage! Go ahead and create a second function that links to /example/result. Your code should look like this:

This code will work fine and you’ll be able to open the page /example/detail (if you’d have an XML record by now too), but, we still need to pass data along.

2.3 Passing data to the webpage

Since there is no code to pass data along yet we should add it. You can call data from the database in controllers too, it just works slightly different. Usually in Odoo you would do this:

It’s not possible to do it like this in the controller though. In the controller we will need to use ‘http.request.env’ to fetch data from a model. As a result your code will look like this:

I’ve also added the function “.sudo()” on this search. Why? Since the website looks at user rights and access rights too you’d need to make sure the users have enough rights. As this is not in the scope of this tutorial I simply add “.sudo()” so that the database query is executed as if it was done by the super administrator user without any security problems.
The final thing to do is to pass this data, that is in the variable companies, to the webpage. How do you do that? Like this:

Now you’re all set on the controller side to open up the page /example/detail and to pass all data to the webpage. The final code of your function will look like this:

Because of doing {‘companies’: companies} in the dictionary all data from all companies will be passed along to the webpage.
Save this code and let us create the second XML record for the webpage in ‘example_webpage.xml’.

2.5 Creating the detail view

Finally, let us create the second webpage and then we’re all done! Open up the ‘example_webpage.xml’ file and create a second XML record, where you also set the page=”True” key on. On this page we will show all company details in a table, which is passed along in the variable “companies”. Have a look at this code and then add it in your XML file:

The controller will know that it has to call this record thanks to the name “detail_page” so when you would save this and update your module everything will work. Since we’ve passed along the dictionary companies we can access all company data. To print all records (in multi company you can have multiple companies) we loop over the records thanks to the t t-foreach code:

Because you’re doing a foreach you can access every company it’s data with the variable “company” later on. As a result we can access any data from the company with “company.field_name”. You can show the data in the webpage with span t-esc=”company.field_name” to print it out:

Finally, save this file, update your module and go to /example/detail. You will now see the following result:
Detail page result

3. Conclusion

Creating webpages and using controllers in Odoo is quite easy. As the Odoo framework has a lot of built in libraries (such as requests, less, bootstrap, font awesome, …) it has never been as easy to create webpages as in Odoo 10. As a result you can create beautiful webpages with any data you want in record times.
Do you want to try the demo code and see the source code of this tutorial? You can view it on my Github account.
Has this tutorial helped you, do you have any feedback or questions? Post away!


Override create functions in Odoo

In this tutorial I will teach you how to override the default create function from Odoo. You will learn how to override the create function and how to change values on a record before storing it in the database.
In this tutorial I will use the ‘res.partner’ model, which is the model from where you can create and edit contacts. I will override this create function, print a message in the terminal and will change the value of a field before storing the record in the database.

1. Inheriting the model

The first thing that you need to do is create a new python file in the ‘models’ folder. Open the ‘models’ folder of your custom module and create a new Python file named ‘res_partner.py’. After creating this file don’t forget to import it in ‘__init__.py’.
Now, open up the ‘res_partner.py’ file, import Odoo, add a class name and inherit the ‘res.partner’ model. Your code should now look like this:

2. Override the create function

Now that we have access to all Odoo methods (thanks to the imports) and now that Odoo knows which model we want to inherit we can start inheriting the create function.
The create function is a default function from Odoo so we can use the API that is provided by Odoo, this is where we use @api.model. After calling @api.model we need to define a function name and pass self and values to the function:

At this point Odoo knows we are doing these operations on the model ‘res.partner’ and that we created a new function with the decorator @api.model.
Tip: Want more information about the Odoo API and the model decorator? See the official documentation
At this point Odoo doesn’t know that we want to inherit an already existing function though. This is where the super call comes in action. With super we can call the original function and override it to change the default behaviour. If you’d like more information about using super see the official Python documentation.
Now, call the super method, pass your class along and tell Python which function you want to override:

So, what exactly does this code do? It tells Python to call the original create function for the model ‘res.partner’ and to apply all the current values to the variable ‘record’.  the variable ‘values’ contains all the values and is passed in the .create() function so that all variables are in ‘record’. In the variable ‘record’ will be all values that you’ve filled in on the form up untill the point you clicked save.

2.1 Changing values in the super

Now, let us go a step further, and add a new field to the model ‘res.partner’ to change a variable the moment we override this function.
Add the following field to your model:

Usually when you override a default function you want to change the value of a field or apply a value. In this example I will set the just created field ‘passed_override_write_function’ to true so that this value is also stored in the database. You can get, or change, any value on this record by calling record[‘field_name’] to change it. Set the variable ‘passed_override_write_function’ to true every time we pass this function:

2.2 Returning the super call

The final step is to return the record and stop the function. Without this your function will not work and the new values will not be returned. Returning the record is very simple:

Let us have a look at the full code. Your ‘res_partner.py’ file should now look like this:

Congratulations, that is all! You’ve now overriden the create method, changed a value in it and stored it in the database. Now create a new contact and click on ‘Save’. The result in the terminal:New contact creation

The result in the database:Database result after override

3. Conclusion

Overriding existing functions in Odoo is quite easy to do. Odoo is built on Python and Python allows you to use super calls, which makes it quite easy to override existing functions.

Do you want to try the demo code and see the source code of this tutorial? You can view it on my Github account.
Has this tutorial helped you, do you have any feedback or questions? Post away!


Connecting PowerBI and Odoo for BI reporting

In this tutorial I will teach you how to connect Odoo and PowerBI to do BI reporting on Odoo data. You will learn how to configure postgreSQL and PowerBI in order to connect them together for real time reporting.
In this tutorial I will work with postgreSQL 9.3, PowerBI Desktop 2.34 and Odoo 10. While this tutorials targets these versions it should work for any Odoo version and postgreSQL 9.3, 9.4, 9.5 and 9.6.

1. Configuring postgreSQL

The first thing that we need to do is to configure postgreSQL. By default postgreSQL does not allow remote connections and if you do configure this it still has to use HTTPS.
As running postgreSQL over SSL is quite advanced and out of scope in this tutorial we’ll configure it without SSL. It is better to run it over SSL as it is more secure so you might want to keep this in the back of your head as a next task.

1.1 Allowing remote connections

Alright, let us start by allowing remote connections to the postgreSQL server. In order to allow this we should edit the ‘pg_hba.conf’ file:

In order to allow remote connections to postgreSQL we should add a line that says postgreSQL that we can connect remote as long as we authenticate. Add the following line at the top of the file:

Your configuration file should now look like this:
pg_hba.conf result
So, what exactly does this do? Let me explain it part by part:

  • Type ‘host’: This tells postgreSQL that it will allow remote connections from a host.
  • Database ‘all’: By saying ‘all’ postgreSQL will allow connecting to any database that exists. If you only want to allow access to one database you can fill in the database name here.
  • User ‘all’: This tells postgreSQL that it’ll allow connections to postgreSQL from any postgreSQL user. If you only want access from one specific user you can fill in the user his name here.
  • CID-ADDRESS: This part allows you to configure from where connections to postgreSQL will be allowed. In this tutorial I’ve set it to ‘’ which means that connections from anywhere around the world will be accepted. In production this should be narrowed down to the range of your network, for example ‘’. Another option is to limit this from a firewall, this is however out of scope for this tutorial.

So to conclude this line of code: we’re allowing connections to postgreSQL from anywhere in the world as long as they authenticate with an username and password.
Now save the file and close it (ctrl+o to save and ctrl+x to close the file if you work with nano).

1.2 Disabling the SSL from postgreSQL

Now that the postgreSQL server allows connections from anywhere there is a second issue. By default postgreSQL will only allow secure connections that run over SSL, this however requires more configuration so I’ve decided to do this tutorial without SSL. If you do want to run postgreSQL over HTTPS you can find more information here.
Disabling the SSL however is very easy, it is just one setting in a configuration file that you need to set to false.
Edit the postgresql.conf file to disable this:

You can find this setting somewhere along line 80, under the ‘Security and Authentication’ block. There is a line that contains the following code:

Change this from true to false. Your result should look like this:
postgresql.conf SSL key
Now save the file (ctrl+o) and close it (ctrl+x).

1.3 Restarting postgreSQL

Congratulations, you’re done configuring postgreSQL. These changes however require a restart before they become active because otherwise postgreSQL does not know about the changes. Restart the postgreSQL service from the command line:

Restarting the postgreSQL server should return an ‘OK’. If this is not the case you’ve probably made a typo, in this case just go over this tutorial again.
If you get the following output you’re ready to connect with PowerBI:
PostgreSQL server restart

2. Configuring PowerBI

After the postgreSQL configuration we can connect with it from PowerBI. If you don’t have PowerBI yet you can download it here.

2.1 Settings up the connection

Open up PowerBI Desktop, click on ‘Get Data’ (1) and then click on ‘More’ (2):
PowerBI data source configuration
A dialog will pop up. Click on ‘Database’ (1), choose for ‘PostgreSQL database’ (2) and then click on ‘Connect’ (3):
PowerBI database
After this a new dialog will show where you can fill in the IP of the postgreSQL server (1) and the name of the database (2), next click on ‘OK’ (3). In my example the postgreSQL runs on the IP ‘’ and I have a database named ‘odoo-test-2’:
postgreSQL ip and database
Finally a dialog will show up where you can fill in the username and the password. You can choose the credentials from a user that only has access to a specific database or you can use a user who has rights to all databases.
Tip: If you don’t know the credentials you can change the password by running the following commands:

In my example I will connect with the main user ‘postgres’ as this user has access to any database and is the administrator user of postgreSQL:
PowerBi authentication
After you click on ‘Connect’ you’ll see a new dialog show up from which you can finally choose from which tables you’d like to get data and make reports from. You’ll get something like this:
Database table selection
Choose the database tables from which you want to get data and where you want to report on and finally click on ‘Load’. From here on you can start connecting relations and create graphs as you’d like. If you’d like to learn more about creating good and advanced PowerBI reports you can follow the official tutorials here.

2.2 Non-encrypted authentication

If you run the postgreSQL service without SSL (as we’ve configured in this tutorial) PowerBI will give you a warning about it, just click on ‘OK’ to connect:
No encryption warning
Tip: If you want to turn off the encryption warnings you can do this from ‘File’ > ‘Options and settings’ > ‘Data source setting’ by clicking on your connection and then clicking on ‘Edit’. After clicking on edit a dialog will show up where you can uncheck ‘Encrypt connections’.

3. Conclusion

Connecting Odoo and PowerBI isn’t the easiest thing to do but it is really worth it. While configuring it takes quite some time it will absolutely be a plus on the longer term. At this time there is no option to create advanced reports and do BI on the data so PowerBI will fill up this gap. After you’ve configured this once and ‘played’ a few hours with PowerBI you’ll notice that it is a very powerful and good reporting tool.
Has this tutorial helped you, do you have any feedback or questions? Post away!


Finding and sending e-mail templates in Odoo

In this tutorial I will teach you how to send e-mail templates in Odoo from the Python code. You’ll learn how to find e-mail templates, how to call them and how to send them to the user. In this tutorial I will continue with the e-mail template that I’ve made in my other tutorial, which you can find here. We’ll create a ‘send e-mail’ button on the contact form and after clicking on this button we will send out the e-mail template.
The result after this tutorial:
Example result e-mail templates

If you just want to follow this tutorial please download and install the sample module from my previous tutorial. You can find the module here.
If you’d like to send out your own e-mail template you can continue reading without using the sample module.

1. Create the send e-mail button

First of all we have to add a button to the existing view. Create a new XML file and inherit the existing contact form:

Now that we’ve inherited the view we should create an xpath in the view in order to add in the button on the form. Write an xpath expression that inserts content before the ‘sheet’ of the form, wrap it in header tags and add a button:

So, what does this code do? It will inherit the existing contact form and will add a button at the top of the form. If you’d install this module right now you would get this as a result:
Contact form example

Now have a closer look at the XML code for the button:

This button will be named ‘send_mail_template’, has the text ‘Send e-mail’ on it and is of the type object. The type ‘object’ tells Odoo that we want to trigger Python code after clicking on the button.

2. Catch the button click

Now that you’ve created the view (XML) side it is time to code the Python side. First of all create a new Python file, create a class in it and inherit the ‘res.partner’ model. Why? Because we will need to execute Python code on the ‘res.partner’ model. Without this inheritance Odoo will not know where to execute our code. Your code should look like this:

Now that you’ve inherited the model ‘res.partner’ we have to add a function that goes off when the user clicks on the button ‘send e-mail’.
The name of your function should be the same as the name of your button because Odoo uses this to execute the Python code. Go ahead and create a function named ‘send_mail_template’:

3. Finding and sending e-mail templates

The final step is to find the e-mail template and send it to the end user.
To find the template you should use self.env.ref to search the template in the database. In this tutorial I’m looking for the e-mail template with the name ‘example_email_template’, which is in the module ‘mail_template_demo’:

It is important to first name the module where the template is in followed by a dot (.) and then the name of the e-mail template. Otherwise Odoo will not find your template.
As a result we will get the variable which contains the link to our e-mail template. Because we only have a ‘pointer’ to this e-mail template we should still find the record itself in the database and trigger the function ‘send_mail’ to push the e-mail out. Your code should look like this:

The self.env will make sure we’re searching on the model ‘mail.template’ (where all e-mail templates are stored) and with browse it can find the correct template. At this point we have the e-mail template but we still need to render it and ‘push’ it to the user. This is exactly what the function ‘send_mail’ does. Since the function ‘send_mail’ needs to know which record it should get data from (to parse it in the e-mail template with jinja2) we will pass along the ID of the current record with self.id.
That’s it! The result of the Python function looks like this:

3.1 The result

You’re all done now! Save all the files, update your modules list and install the module. When you go to the contact form and click on the button ‘Send e-mail’ you’ll see an e-mail in your inbox within a few minutes:
Send e-mail result

4. Conclusion

Finding and sending out e-mail templates in Odoo is actually really easy. It only requires a few lines of Python code and all the rest is handled by Odoo itself.

Do you want to try the demo code and see the source code of this tutorial? You can view it on my Github account.
Has this tutorial helped you, do you have any feedback or questions? Post away!


Creating e-mail templates in Odoo

In this tutorial I will teach you how to create e-mail templates in Odoo. You will learn how to create e-mail templates in XML and how to add them to the available templates. An example of the result after this tutorial:
E-mail templates example
In this tutorial I will create a new e-mail template to congratulate you on creating your own e-mail template and I will show you how to parse data from the current record in to the template with Jinja2.

1. Adding the dependencies

The first thing that you need to do is add a dependency to other modules that you’ll need. Open up the __manifest.py__ file (or __openerp__.py on Odoo 8 and 9) and find the line ‘depends’. In this list you should add all the modules that you need in your custom developed module. If you want to create a new e-mail template you will need to inherit the mail module in this list. Without this inherit you won’t be able to create your own e-mail templates as Odoo wouldn’t recognize the model. In this tutorial I will create an e-mail template that can be used on the contacts form so you’ll also need the contacts module for this tutorial. Go ahead and add them both in, the result should look like this:

Now save the file and close it, it is time to create the template itself!

2. Creating the e-mail template

Now that you have the correct dependencies it is time to create the e-mail template itself. In Odoo e-mail templates are build in XML and the moment that you would send the e-mail template to somebody the Jinja2 will render your e-mail and fill it up with the corresponding data.
Create yourself a new XML file and add the default tags in the file. Since we’re creating an e-mail template we should use the noupdate=”1″ tag though. So, why do we use this tag? If you wouldn’t use it the e-mail template would be updated (and overridden) every time that you would update the module, which would result in you losing data if you’ve changed something. Your XML file should now look like this:

The next step is to create a new XML record. Just have a look at the following code and try to understand it, I will explain every line in detail under the code.

So, what exactly does this do? The very first line, which holds the record id and record model are very important. Every e-mail template that you ever want to create should be to the model ‘mail.template’. This is where all e-mail templates are saved and you should add yours there too. Now, let us go over it line by the line.

  • The ‘name’ field: This gives your e-mail template a name, which is also shown if you look at all templates under Settings > Technical > Email > Templates.
  • The ’email_from’ field: This will show the e-mail from which this e-mail is sent. This is where Odoo gets interesting! You can use ${} to get data from a record and to use this for filling in the data automatically with Jinja2. I’ll get into detail about this later on in this tutorial (see chapter 3).
  • The ‘subject’ field: This will be the title of the e-mail that is being sent to the user.
  • The ’email_to’ field: This will contain the email address to who the e-mail should be sent.
  • The ‘lang’ field: This field will make sure that the e-mail is being sent in the correct language. This field in combination with translations can be used to create multi-language e-mail templates.
  • The ‘model_id’ field: This field will tell your e-mail template on which model it will be used and where it should get data from. It always starts with ‘model_’ and should then contain the model name. It is important to replace the dots in a model name by underscores. So the model ‘res.partner’ should become ‘res_partner’.
  • The ‘auto_delete’ field: If this field is set to true it will permanently delete the e-mail after sending it, if the field is set to false the e-mail will be kept in Odoo.
  • The ‘body_html’ field: This is where you can design the content of the e-mail. You can use HTML and Jinja2 variables in this part too so you can style the template and pre-fill data before it is being sent. All the content that contains HTML or variables should be within CDATA Click here for more information about CDATA.

There, you now have a functioning e-mail template! Finally we should add some content in it. An example:

That is all, you’ve just created your very first e-mail template! Your template should now look like this:

After saving this file and installing the module you will have the e-mail template available. If you’d like to know what exactly ${} does and how you can use Jinja2 to automatically fill in data just continue reading! If you already know this or don’t want to know you can go to chapter 4.

3. Using jinja2 variables for parsing e-mail templates

Odoo e-mail templates come with jinja2 by default. This means that you can access any value on a record and fill it in on the e-mail automatically. Let us go back to the code from the e-mail template we just made. In the subject field we had the following code:

What exactly does this do? By calling ${} Jinja2 knows that this part of the XML should be parsed. By default ‘object’ will be able to access all values from the existing model, which is in this tutorial the model ‘res.partner’. If we would send out this e-mail template from a contact named ‘Administrator’ the subject would become “Congratz Administrator”:
Example rendered e-mail template

If you would want to get the contact his language for example you can access it by simply doing:

If you’d want to get the value from another model that is connected to ‘res.partner’ (many2one, many2many fields) you can also access the value too:

If you would like to go even further and create dynamic e-mail templates you can do this too. For example if you would only want to send a part of the text if the contact has a website you could do this:

In this example this part of the text would only be added to the e-mail if the contact has a website filled in on his form.
As you can see Jinja2 has quite some options and you can go a lot further. If you’d like to learn more you can find more information about Jinja2 and how it works on their website.

4. Conclusion

Creating e-mail templates in Odoo is quite easy and only requires you to write some XML. There are a lot of abilities for e-mail templates such as if/else statements, content parsing, dynamic content and so on thanks to Jinja2.
While creating e-mail templates is quite easy in Odoo it can get rather complex if you would like to use multiple if statements or dynamic content. It is always wise to test your e-mail templates in detail before placing it in production.

Do you want to try the demo code and see the source code of this tutorial? You can view it on my Github account.
Has this tutorial helped you, do you have any feedback or questions? Post away!