Studio Indie
2024-01-20T04:29:06Z
https://studioindie.co
Studio Indie
hello@studioindie.co
Starter Guide for HEEx Templates
2024-01-20T04:29:06Z
https://studioindie.co/blog/heex-guide/
<p>The <a href="https://hexdocs.pm/phoenix_live_view/0.17.14/assigns-eex.html">HTML EEx templates</a> is the built-in templating engine for <a href="https://phoenixframework.org/">Phoenix framework</a>.
This reference is helpful for people familiar with templating languages like Nunjucks or Jinja.</p>
<p>We’ll be covering the following:
</p><div class="table-of-contents"><ul><li><a href="https://studioindie.co/blog/heex-guide/#variables">Variables</a></li><li><a href="https://studioindie.co/blog/heex-guide/#logic">Logic</a></li><li><a href="https://studioindie.co/blog/heex-guide/#include">Include</a></li><li><a href="https://studioindie.co/blog/heex-guide/#raw-html">Raw HTML</a></li><li><a href="https://studioindie.co/blog/heex-guide/#comments">Comments</a></li><li><a href="https://studioindie.co/blog/heex-guide/#references">References</a></li></ul></div><p></p>
<p>Using <a href="https://hexdocs.pm/phoenix_live_view/0.17.14/Phoenix.LiveView.html">Phoenix LiveView</a>, we can render a view either by defining <code>render/1</code> function, or <a href="https://hexdocs.pm/phoenix_live_view/0.17.14/Phoenix.LiveView.html#module-colocating-templates">placing template code in a file</a>.</p>
<p>For simplicity, let’s assume the module defines <code>render/1</code> function, which returns a HEEx template, defined using a <code>~H</code> sigil.</p>
<pre class="language-elixir"><code class="language-elixir"><span class="token keyword">def</span> <span class="token function">render</span><span class="token punctuation">(</span>assigns<span class="token punctuation">)</span> <span class="token keyword">do</span><br /> ~<span class="token module class-name">H</span><span class="token string">"""<br /> template content here<br /> """</span><br /><span class="token keyword">end</span></code></pre>
<p>The <code>assigns</code> parameter can be either an Elixir <a href="https://hexdocs.pm/elixir/Keyword.html">Keyword</a> or a <a href="https://hexdocs.pm/elixir/Map.html">Map</a>, accessible within template code.</p>
<h2 id="variables" tabindex="-1">Variables</h2>
<pre class="language-erb"><code class="language-erb"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span><span class="token ruby language-ruby"> <span class="token variable">@name</span> </span><span class="token delimiter punctuation">%></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></code></pre>
<p>Accessing the value using <code>@</code> when the value is <code>undefined</code> ends up in an exception.
So, in case you need to provide a fallback in the template, you have to access the value through <code>assigns</code>, and supply a fallback.</p>
<pre class="language-erb"><code class="language-erb"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span><span class="token ruby language-ruby"> assigns<span class="token punctuation">[</span><span class="token symbol">:name</span><span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token string-literal"><span class="token string">"Untitled"</span></span> </span><span class="token delimiter punctuation">%></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></code></pre>
<p>HEEx templates comes with HTML validation and shorter interpolation syntax of attributes.
You can provide a value to HTML attributes using <code>key={value}</code> syntax. HEEx will remove the attribute from rendered HTML when the value is <code>false</code>.</p>
<pre class="language-erb"><code class="language-erb"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">data-user-state</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>{@state}</span><span class="token punctuation">></span></span> ... <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></code></pre>
<pre class="language-erb"><code class="language-erb"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>{@classes}</span><span class="token punctuation">></span></span><br /> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span>Hello <span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span><span class="token ruby language-ruby"> <span class="token variable">@username</span> </span><span class="token delimiter punctuation">%></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span><br /><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></code></pre>
<p>…will magically render to:</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>highlight bold<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><br /> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span>Hello joe<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span><br /><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></code></pre>
<h2 id="logic" tabindex="-1">Logic</h2>
<h3 id="if%E2%80%A6-else%E2%80%A6" tabindex="-1">If… else…</h3>
<pre class="language-erb"><code class="language-erb"><span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span><span class="token ruby language-ruby"> <span class="token keyword">if</span> <span class="token variable">@state</span> <span class="token operator">==</span> <span class="token string-literal"><span class="token string">"new"</span></span> <span class="token keyword">do</span> </span><span class="token delimiter punctuation">%></span></span><br /> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span>Newly joined.<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span><br /><span class="token erb language-erb"><span class="token delimiter punctuation"><%</span><span class="token ruby language-ruby"> <span class="token keyword">end</span> </span><span class="token delimiter punctuation">%></span></span></code></pre>
<pre class="language-erb"><code class="language-erb"><span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span><span class="token ruby language-ruby"> <span class="token keyword">if</span> <span class="token variable">@state</span> <span class="token operator">==</span> <span class="token string-literal"><span class="token string">"new"</span></span> <span class="token keyword">do</span> </span><span class="token delimiter punctuation">%></span></span><br /> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span>Newly joined.<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span><br /><span class="token erb language-erb"><span class="token delimiter punctuation"><%</span><span class="token ruby language-ruby"> <span class="token keyword">else</span> </span><span class="token delimiter punctuation">%></span></span><br /> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span>Veteran.<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span><br /><span class="token erb language-erb"><span class="token delimiter punctuation"><%</span><span class="token ruby language-ruby"> <span class="token keyword">end</span> </span><span class="token delimiter punctuation">%></span></span></code></pre>
<h3 id="loop" tabindex="-1">Loop</h3>
<p>Consider a user data passed down through <code>assigns</code> as:</p>
<pre class="language-elixir"><code class="language-elixir"><span class="token function">assign</span><span class="token punctuation">(</span>conn<span class="token punctuation">,</span> <span class="token atom symbol">:users</span><span class="token punctuation">,</span><br /> <span class="token attr-name">users:</span> <span class="token punctuation">[</span><br /> <span class="token punctuation">%</span><span class="token punctuation">{</span><span class="token attr-name">name:</span> <span class="token string">'Jamie Houston'</span><span class="token punctuation">,</span> <span class="token attr-name">age:</span> <span class="token number">20</span><span class="token punctuation">}</span><span class="token punctuation">,</span><br /> <span class="token punctuation">%</span><span class="token punctuation">{</span><span class="token attr-name">name:</span> <span class="token string">'Barbara John'</span><span class="token punctuation">,</span> <span class="token attr-name">age:</span> <span class="token number">23</span><span class="token punctuation">}</span><br /> <span class="token punctuation">]</span><br /> <span class="token punctuation">)</span></code></pre>
<p>…you can loop over the array using:</p>
<pre class="language-erb"><code class="language-erb"><span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span><span class="token ruby language-ruby"> <span class="token keyword">for</span> user <span class="token operator"><</span><span class="token operator">-</span> <span class="token variable">@users</span> <span class="token keyword">do</span> </span><span class="token delimiter punctuation">%></span></span><br /> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span><span class="token ruby language-ruby"> user<span class="token punctuation">.</span>name </span><span class="token delimiter punctuation">%></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><br /> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>age<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span><span class="token ruby language-ruby"> user<span class="token punctuation">.</span>age </span><span class="token delimiter punctuation">%></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><br /><span class="token erb language-erb"><span class="token delimiter punctuation"><%</span><span class="token ruby language-ruby"> <span class="token keyword">end</span> </span><span class="token delimiter punctuation">%></span></span></code></pre>
<h2 id="include" tabindex="-1">Include</h2>
<p>To replicate the function of <code>include</code> tag from Nunjucks and Jinja, to render another template file, you can use <code>render/2</code> within templates</p>
<pre class="language-erb"><code class="language-erb"><span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span><span class="token ruby language-ruby"> render <span class="token string-literal"><span class="token string">"another-template.html"</span></span><span class="token punctuation">,</span> assigns </span><span class="token delimiter punctuation">%></span></span></code></pre>
<h2 id="raw-html" tabindex="-1">Raw HTML</h2>
<p>HEEx, by default, escape all HTML content. You can use <code>raw</code> to allow unescaped HTML.</p>
<pre class="language-erb"><code class="language-erb"><span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span><span class="token ruby language-ruby"> raw <span class="token string-literal"><span class="token string">"<hello/>"</span></span> </span><span class="token delimiter punctuation">%></span></span></code></pre>
<h2 id="comments" tabindex="-1">Comments</h2>
<pre class="language-elixir"><code class="language-elixir"><<span class="token punctuation">%</span><span class="token comment"># This is a comment. %></span><br /><br /><span class="token operator"><</span><span class="token punctuation">%</span><span class="token comment"># And,</span><br /> <span class="token operator">...</span>this is a multiline comment<span class="token punctuation">.</span><br /><span class="token punctuation">%</span><span class="token operator">></span></code></pre>
<h2 id="references" tabindex="-1">References</h2>
<ul>
<li><a href="https://hexdocs.pm/phoenix/1.6.5/views.html">Views and Templates Documentation</a></li>
<li><a href="https://hexdocs.pm/phoenix_live_view/0.17.14/assigns-eex.html">Assigns and HEEx templates</a></li>
<li><a href="http://web.archive.org/web/20230528215637/https://samuelmullen.com/articles/phoenix-templates/">Phoenix Templates by Samuel Mullen</a></li>
</ul>
Introducing Ask About Design
2022-04-14T09:45:18Z
https://studioindie.co/blog/ask-about-design/
<p>We launched our first product, <a href="https://askaboutdesign.com/">Ask About Design</a>, in January 2022.</p>
<p>Ask About Design will be a set of tools for designers and researchers, to test and optimize visual languages, information architectures, and user experiences.</p>