<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="generator" content="ExDoc v0.19.1"> <title>EEx.Engine – EEx v1.7.2</title> <link rel="stylesheet" href="dist/app-240d7fc7e5.css" /> <link rel="canonical" href="https://hexdocs.pm/eex/v1.7/EEx.Engine.html" /> <script src="dist/sidebar_items-b44f37d3d1.js"></script> </head> <body data-type="modules"> <script>try { if(localStorage.getItem('night-mode')) document.body.className += ' night-mode'; } catch (e) { }</script> <div class="main"> <button class="sidebar-button sidebar-toggle"> <span class="icon-menu" aria-hidden="true"></span> <span class="sr-only">Toggle Sidebar</span> </button> <button class="sidebar-button night-mode-toggle"> <span class="icon-theme" aria-hidden="true"></span> <span class="sr-only">Toggle Theme</span> </button> <section class="sidebar"> <a href="http://elixir-lang.org/docs.html" class="sidebar-projectLink"> <div class="sidebar-projectDetails"> <h1 class="sidebar-projectName"> EEx </h1> <h2 class="sidebar-projectVersion"> v1.7.2 </h2> </div> <img src="assets/logo.png" alt="EEx" class="sidebar-projectImage"> </a> <form class="sidebar-search" action="search.html"> <button type="submit" class="search-button"> <span class="icon-search" aria-hidden="true"></span> </button> <input name="q" type="text" id="search-list" class="search-input" placeholder="Search" aria-label="Search" autocomplete="off" /> </form> <ul class="sidebar-listNav"> <li><a id="extras-list" href="#full-list">Pages</a></li> <li><a id="modules-list" href="#full-list">Modules</a></li> <li><a id="exceptions-list" href="#full-list">Exceptions</a></li> </ul> <div class="gradient"></div> <ul id="full-list" class="sidebar-fullList"></ul> </section> <section class="content"> <div class="content-outer"> <div id="content" class="content-inner"> <h1> <small class="visible-xs">EEx v1.7.2</small> EEx.Engine <small>behaviour</small> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L1" title="View Source" class="view-source" rel="help"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> </h1> <section id="moduledoc"> <p>Basic EEx engine that ships with Elixir.</p> <p>An engine needs to implement six functions:</p> <ul> <li><p><code class="inline">init(opts)</code> - called at the beginning of every text and it must return the initial state.</p> </li> <li><p><code class="inline">handle_body(state)</code> - receives the state of the document and it must return a quoted expression.</p> </li> <li><p><code class="inline">handle_text(state, text)</code> - it receives the state, the text and must return a new quoted expression.</p> </li> <li><p><code class="inline">handle_expr(state, marker, expr)</code> - it receives the state, the marker, the expr and must return a new state.</p> </li> <li><p><code class="inline">handle_begin(state)</code> - called every time there a new state is needed with an empty buffer. Typically called for do/end blocks, case expressions, anonymous functions, etc</p> </li> <li><p><code class="inline">handle_end(state)</code> - opposite of <code class="inline">handle_begin(state)</code> and it must return quoted expression</p> <p>The marker is what follows exactly after <code class="inline"><%</code>. For example, <code class="inline"><% foo %></code> has an empty marker, but <code class="inline"><%= foo %></code> has <code class="inline">"="</code> as marker. The allowed markers so far are: </p> <ul> <li><code class="inline">""</code> </li> <li><code class="inline">"="</code> </li> <li><code class="inline">"/"</code> </li> <li><code class="inline">"|"</code> </li> </ul> <p>Markers <code class="inline">"/"</code> and <code class="inline">"|"</code> are only for use in custom EEx engines and are not implemented by default. Using them without the implementation raises <a href="EEx.SyntaxError.html"><code class="inline">EEx.SyntaxError</code></a>.</p> <p>If your engine does not implement all markers, please ensure that <a href="#handle_expr/3"><code class="inline">handle_expr/3</code></a> falls back to <a href="EEx.Engine.html#handle_expr/3"><code class="inline">EEx.Engine.handle_expr/3</code></a> to raise the proper error message.</p> <p>Read <a href="#handle_expr/3"><code class="inline">handle_expr/3</code></a> below for more information about the markers implemented by default by this engine.</p> </li> </ul> <p><a href="EEx.Engine.html#content"><code class="inline">EEx.Engine</code></a> can be used directly if one desires to use the default implementations for the functions above.</p> </section> <section id="summary" class="details-list"> <h1 class="section-heading"> <a class="hover-link" href="#summary"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this section</span> </a> Summary </h1> <div class="summary-types summary"> <h2> <a href="#types">Types</a> </h2> <div class="summary-row"> <div class="summary-signature"> <a href="#t:state/0">state()</a> </div> </div> </div> <div class="summary-functions summary"> <h2> <a href="#functions">Functions</a> </h2> <div class="summary-row"> <div class="summary-signature"> <a href="#handle_assign/1">handle_assign(arg)</a> </div> <div class="summary-synopsis"><p>Handles assigns in quoted expressions</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#handle_begin/1">handle_begin(previous)</a> </div> <div class="summary-synopsis"><p>Returns an empty string as the new buffer</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#handle_body/1">handle_body(quoted)</a> </div> <div class="summary-synopsis"><p>The default implementation simply returns the given expression</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#handle_end/1">handle_end(quoted)</a> </div> <div class="summary-synopsis"><p>End of the new buffer</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#handle_expr/3">handle_expr(buffer, marker, expr)</a> </div> <div class="summary-synopsis"><p>Implements expressions according to the markers</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#handle_text/2">handle_text(buffer, text)</a> </div> <div class="summary-synopsis"><p>The default implementation simply concatenates text to the buffer</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#init/1">init(opts)</a> </div> <div class="summary-synopsis"><p>Returns an empty string as initial buffer</p> </div> </div> </div> <div class="summary-callbacks summary"> <h2> <a href="#callbacks">Callbacks</a> </h2> <div class="summary-row"> <div class="summary-signature"> <a href="#c:handle_begin/1">handle_begin(state)</a> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#c:handle_body/1">handle_body(state)</a> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#c:handle_end/1">handle_end(state)</a> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#c:handle_expr/3">handle_expr(state, marker, expr)</a> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#c:handle_text/2">handle_text(state, text)</a> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#c:init/1">init(opts)</a> </div> </div> </div> </section> <section id="types" class="details-list"> <h1 class="section-heading"> <a class="hover-link" href="#types"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this section</span> </a> Types </h1> <div class="types-list"> <div class="detail" id="t:state/0"> <div class="detail-header"> <a href="#t:state/0" class="detail-link" title="Link to this type"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this type</span> </a> <span class="signature">state()</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L50" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>state() :: <a href="https://hexdocs.pm/elixir/typespecs.html#built-in-types">term</a>()</pre> </div> </div> <section class="docstring"> </section> </div> </div> </section> <section id="functions" class="details-list"> <h1 class="section-heading"> <a class="hover-link" href="#functions"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this section</span> </a> Functions </h1> <div class="detail" id="handle_assign/1"> <div class="detail-header"> <a href="#handle_assign/1" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">handle_assign(arg)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L113" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>handle_assign(<a href="https://hexdocs.pm/elixir/Macro.html#t:t/0">Macro.t</a>()) :: <a href="https://hexdocs.pm/elixir/Macro.html#t:t/0">Macro.t</a>()</pre> </div> </div> <section class="docstring"> <p>Handles assigns in quoted expressions.</p> <p>A warning will be printed on missing assigns. Future versions will raise.</p> <p>This can be added to any custom engine by invoking <a href="#handle_assign/1"><code class="inline">handle_assign/1</code></a> with <a href="https://hexdocs.pm/elixir/Macro.html#prewalk/2"><code class="inline">Macro.prewalk/2</code></a>:</p> <pre><code class="nohighlight makeup elixir"><span class="kd">def</span><span class="w"> </span><span class="nf">handle_expr</span><span class="p" data-group-id="1345380839-1">(</span><span class="n">buffer</span><span class="p">,</span><span class="w"> </span><span class="n">token</span><span class="p">,</span><span class="w"> </span><span class="n">expr</span><span class="p" data-group-id="1345380839-1">)</span><span class="w"> </span><span class="k" data-group-id="1345380839-2">do</span><span class="w"> </span><span class="n">expr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">prewalk</span><span class="p" data-group-id="1345380839-3">(</span><span class="n">expr</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="nc">EEx.Engine</span><span class="o">.</span><span class="n">handle_assign</span><span class="o">/</span><span class="mi">1</span><span class="p" data-group-id="1345380839-3">)</span><span class="w"> </span><span class="nc">EEx.Engine</span><span class="o">.</span><span class="n">handle_expr</span><span class="p" data-group-id="1345380839-4">(</span><span class="n">buffer</span><span class="p">,</span><span class="w"> </span><span class="n">token</span><span class="p">,</span><span class="w"> </span><span class="n">expr</span><span class="p" data-group-id="1345380839-4">)</span><span class="w"> </span><span class="k" data-group-id="1345380839-2">end</span></code></pre> </section> </div> <div class="detail" id="handle_begin/1"> <div class="detail-header"> <a href="#handle_begin/1" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">handle_begin(previous)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L148" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> </div> <section class="docstring"> <p>Returns an empty string as the new buffer.</p> </section> </div> <div class="detail" id="handle_body/1"> <div class="detail-header"> <a href="#handle_body/1" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">handle_body(quoted)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L162" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> </div> <section class="docstring"> <p>The default implementation simply returns the given expression.</p> </section> </div> <div class="detail" id="handle_end/1"> <div class="detail-header"> <a href="#handle_end/1" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">handle_end(quoted)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L155" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> </div> <section class="docstring"> <p>End of the new buffer.</p> </section> </div> <div class="detail" id="handle_expr/3"> <div class="detail-header"> <a href="#handle_expr/3" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">handle_expr(buffer, marker, expr)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L198" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> </div> <section class="docstring"> <p>Implements expressions according to the markers.</p> <pre><code class="nohighlight makeup elixir"><span class="o"><</span><span class="p">%</span><span class="w"> </span><span class="nc">Elixir</span><span class="w"> </span><span class="n">expression</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">inline</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">output</span><span class="w"> </span><span class="p">%</span><span class="o">></span><span class="w"> </span><span class="o"><</span><span class="p">%</span><span class="o">=</span><span class="w"> </span><span class="nc">Elixir</span><span class="w"> </span><span class="n">expression</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">replace</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="p">%</span><span class="o">></span><span class="w"> </span><span class="o"><</span><span class="p">%</span><span class="o">/</span><span class="w"> </span><span class="nc">Elixir</span><span class="w"> </span><span class="n">expression</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="k">raise</span><span class="w"> </span><span class="nc">EEx.SyntaxError</span><span class="p">,</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">implemented</span><span class="w"> </span><span class="n">by</span><span class="w"> </span><span class="n">custom</span><span class="w"> </span><span class="n">engines</span><span class="w"> </span><span class="p">%</span><span class="o">></span><span class="w"> </span><span class="o"><</span><span class="p">%</span><span class="o">|</span><span class="w"> </span><span class="nc">Elixir</span><span class="w"> </span><span class="n">expression</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="k">raise</span><span class="w"> </span><span class="nc">EEx.SyntaxError</span><span class="p">,</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">implemented</span><span class="w"> </span><span class="n">by</span><span class="w"> </span><span class="n">custom</span><span class="w"> </span><span class="n">engines</span><span class="w"> </span><span class="p">%</span><span class="o">></span></code></pre> <p>All other markers are not implemented by this engine.</p> </section> </div> <div class="detail" id="handle_text/2"> <div class="detail-header"> <a href="#handle_text/2" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">handle_text(buffer, text)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L169" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> </div> <section class="docstring"> <p>The default implementation simply concatenates text to the buffer.</p> </section> </div> <div class="detail" id="init/1"> <div class="detail-header"> <a href="#init/1" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">init(opts)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L141" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> </div> <section class="docstring"> <p>Returns an empty string as initial buffer.</p> </section> </div> </section> <section id="callbacks" class="details-list"> <h1 class="section-heading"> <a class="hover-link" href="#callbacks"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this section</span> </a> Callbacks </h1> <div class="detail" id="c:handle_begin/1"> <div class="detail-header"> <a href="#c:handle_begin/1" class="detail-link" title="Link to this callback"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this callback</span> </a> <span class="signature">handle_begin(state)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L56" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>handle_begin(<a href="#t:state/0">state</a>()) :: <a href="#t:state/0">state</a>()</pre> </div> </div> <section class="docstring"> </section> </div> <div class="detail" id="c:handle_body/1"> <div class="detail-header"> <a href="#c:handle_body/1" class="detail-link" title="Link to this callback"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this callback</span> </a> <span class="signature">handle_body(state)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L53" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>handle_body(<a href="#t:state/0">state</a>()) :: <a href="https://hexdocs.pm/elixir/Macro.html#t:t/0">Macro.t</a>()</pre> </div> </div> <section class="docstring"> </section> </div> <div class="detail" id="c:handle_end/1"> <div class="detail-header"> <a href="#c:handle_end/1" class="detail-link" title="Link to this callback"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this callback</span> </a> <span class="signature">handle_end(state)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L57" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>handle_end(<a href="#t:state/0">state</a>()) :: <a href="https://hexdocs.pm/elixir/Macro.html#t:t/0">Macro.t</a>()</pre> </div> </div> <section class="docstring"> </section> </div> <div class="detail" id="c:handle_expr/3"> <div class="detail-header"> <a href="#c:handle_expr/3" class="detail-link" title="Link to this callback"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this callback</span> </a> <span class="signature">handle_expr(state, marker, expr)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L55" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>handle_expr(<a href="#t:state/0">state</a>(), marker :: <a href="https://hexdocs.pm/elixir/String.html#t:t/0">String.t</a>(), expr :: <a href="https://hexdocs.pm/elixir/Macro.html#t:t/0">Macro.t</a>()) :: <a href="#t:state/0">state</a>()</pre> </div> </div> <section class="docstring"> </section> </div> <div class="detail" id="c:handle_text/2"> <div class="detail-header"> <a href="#c:handle_text/2" class="detail-link" title="Link to this callback"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this callback</span> </a> <span class="signature">handle_text(state, text)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L54" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>handle_text(<a href="#t:state/0">state</a>(), text :: <a href="https://hexdocs.pm/elixir/String.html#t:t/0">String.t</a>()) :: <a href="#t:state/0">state</a>()</pre> </div> </div> <section class="docstring"> </section> </div> <div class="detail" id="c:init/1"> <div class="detail-header"> <a href="#c:init/1" class="detail-link" title="Link to this callback"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this callback</span> </a> <span class="signature">init(opts)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/eex/lib/eex/engine.ex#L52" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>init(opts :: <a href="https://hexdocs.pm/elixir/typespecs.html#built-in-types">keyword</a>()) :: <a href="#t:state/0">state</a>()</pre> </div> </div> <section class="docstring"> </section> </div> </section> <footer class="footer"> <p> <span class="line"> Built using <a href="https://github.com/elixir-lang/ex_doc" title="ExDoc" target="_blank" rel="help noopener">ExDoc</a> (v0.19.1), </span> <span class="line"> designed by <a href="https://twitter.com/dignifiedquire" target="_blank" rel="noopener" title="@dignifiedquire">Friedel Ziegelmayer</a>. </span> </p> </footer> </div> </div> </section> </div> <script src="dist/app-a0c90688fa.js"></script> </body> </html>