Do you want to pick up from where you left of?
Take me there

Embedded Elixir (EEx)

Much like Ruby has ERB and Java has JSPs, Elixir has EEx, or Embedded Elixir. With EEx we can embed and evaluate Elixir inside strings.


The EEx API supports working with strings and files directly. The API is divided into three main components: simple evaluation, function definitions, and compilation to AST.


Using eval_string/3 and eval_file/2 we can perform a simple evaluation against a string or file contents. This is the simplest API but the slowest since code is evaluated and not compiled.

iex> EEx.eval_string "Hi, <%= name %>", [name: "Sean"]
"Hi, Sean"


The fastest, and preferred, method of using EEx is to embed our template into a module so it can be compiled. For this we need our template at compile time, along with the function_from_string/5 and function_from_file/5 macros.

Let’s move our greeting to another file and generate a function for our template:

# greeting.eex
Hi, <%= name %>

defmodule Example do
  require EEx
  EEx.function_from_file(:def, :greeting, "greeting.eex", [:name])

iex> Example.greeting("Sean")
"Hi, Sean"


Lastly, EEx provides us a way to directly generate Elixir AST from a string or file using compile_string/2 or compile_file/2. This API is primarily used by the aforementioned APIs but is available should you wish to implement your own handling of embedded Elixir.


By default there are four supported tags in EEx:

<% Elixir expression - inline with output %>
<%= Elixir expression - replace with result %>
<%% EEx quotation - returns the contents inside %>
<%# Comments - they are discarded from source %>

All expressions that wish to output must use the equals sign (=). It’s important to note that while other templating languages treat clauses like if in a special way, EEx does not. Without = nothing will be output:

<%= if true do %>
  A truthful statement
<% else %>
  A false statement
<% end %>


By default Elixir uses the EEx.SmartEngine, which includes support for assignments (like @name):

iex> EEx.eval_string "Hi, <%= @name %>", assigns: [name: "Sean"]
"Hi, Sean"

The EEx.SmartEngine assignments are useful because assignments can be changed without requiring template compilation.

Interested in writing your own engine? Check out the EEx.Engine behaviour to see what’s required.

Caught a mistake or want to contribute to the lesson? Edit this lesson on GitHub!