View Source README
Easily create beautiful emails using MJML right from Elixir!
Contents
installation
Installation
Available in Hex, the package can be installed by adding mjml_eex
to your list of
dependencies in mix.exs
:
def deps do
[
{:mjml_eex, "~> 0.5.0"}
]
end
Documentation can be found at https://hexdocs.pm/mjml_eex.
supporting-mjml-eex
Supporting MJML EEx
If you rely on this library to generate awesome looking emails for your application, it would much appreciated if you can give back to the project in order to help ensure its continued development.
Checkout my GitHub Sponsorship page if you want to help out!
gold-sponsors
Gold Sponsors

silver-sponsors
Silver Sponsors

bronze-sponsors
Bronze Sponsors

using-mjml-eex
Using MJML EEx
basic-usage
Basic Usage
Add {:mjml_eex, "~> 0.5.0"}
to your mix.exs
file and run mix deps.get
. After you have that in place, you
can go ahead and create a template module like so:
defmodule BasicTemplate do
use MjmlEEx, mjml_template: "basic_template.mjml.eex"
end
And the accompanying MJML EEx template basic_template.mjml.eex
(note that the path is relative to the calling
module path):
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-divider border-color="#F45E43"></mj-divider>
<mj-text font-size="20px" color="#F45E43">Hello <%= @first_name %> <%= @last_name %>!</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
With those two in place, you can now run BasicTemplate.render(first_name: "Alex", last_name: "Koutmos")
and you
will get back an HTML document that can be emailed to users.
using-functions-from-template-module
Using Functions from Template Module
You can also call functions from your template module if they exist in your MJML EEx template using the following module declaration:
defmodule FunctionTemplate do
use MjmlEEx, mjml_template: "function_template.mjml.eex"
defp generate_full_name(first_name, last_name) do
"#{first_name} #{last_name}"
end
end
In conjunction with the following template:
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-divider border-color="#F45E43"></mj-divider>
<mj-text font-size="20px" color="#F45E43">Hello <%= generate_full_name(@first_name, @last_name) %>!</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
In order to render the email you would then call: FunctionTemplate.render(first_name: "Alex", last_name: "Koutmos")
using-components
Using Components
In addition to compiling single MJML EEx templates, you can also create MJML partials and include them
in other MJML templates AND components using the special render_component
function. With the following
modules:
defmodule FunctionTemplate do
use MjmlEEx, mjml_template: "component_template.mjml.eex"
end
defmodule HeadBlock do
use MjmlEEx.Component
@impl true
def render(_opts) do
"""
<mj-head>
<mj-title>Hello world!</mj-title>
<mj-font name="Roboto" href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500"></mj-font>
</mj-head>
"""
end
end
And the following template:
<mjml>
<%= render_component HeadBlock %>
<mj-body>
<mj-section>
<mj-column>
<mj-divider border-color="#F45E43"></mj-divider>
<mj-text font-size="20px" color="#F45E43">Hello <%= generate_full_name(@first_name, @last_name) %>!</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
Be sure to look at the MjmlEEx.Component
for additional usage information as you can also pass options
to your template and use them when generating the partial string.
using-layouts
Using Layouts
Often times, you'll want to create an Email skeleton or layout using MJML, and then inject your template into that layout. MJML EEx supports this functionality which makes it really easy to have business branded emails application wide without having to copy and paste the same boilerplate in every template.
To create a layout, define a layout module like so:
defmodule BaseLayout do
use MjmlEEx.Layout, mjml_layout: "base_layout.mjml.eex"
end
And an accompanying layout like so:
<mjml>
<mj-head>
<mj-title>Say hello to card</mj-title>
<mj-font name="Roboto" href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500"></mj-font>
<mj-attributes>
<mj-all font-family="Montserrat, Helvetica, Arial, sans-serif"></mj-all>
<mj-text font-weight="400" font-size="16px" color="#000000" line-height="24px"></mj-text>
<mj-section padding="<%= @padding %>"></mj-section>
</mj-attributes>
</mj-head>
<%= @inner_content %>
</mjml>
As you can see, you can include assigns in your layout template (like @padding
), but you also need to
include a mandatory @inner_content
expression. That way, MJML EEx knowns where to inject your template
into the layout. With that in place, you just need to tell your template module what layout to use (if
you are using a layout that is):
defmodule MyTemplate do
use MjmlEEx,
mjml_template: "my_template.mjml.eex",
layout: BaseLayout
end
And your template file can contain merely the parts that you need for that particular template:
<mj-body> ... </mj-body>
attribution
Attribution
- The logo for the project is an edited version of an SVG image from the unDraw project
- The Elixir MJML library that this library builds on top of MJML
- The Rust MRML library that provides the MJML compilation functionality MRML