私たちはHEExが大好きです -- YouTube チャンネル daimon.ex 第2回解説
動画
HEExとは何か
HEEx(エイチイーイーエックス、ヒークス)は2021年夏に登場した比較的新しいHTMLテンプレートエンジンです。ElixirにはEExという名前の汎用的な(HTMLに特化しない)テンプレートエンジンが従来からあります。HEExをEExの拡張版です。
HTMLタグの属性にアサインを埋め込む場合の新しい書き方
HEExの第1の特徴は、HTMLタグの内側、属性の値にアサインを埋め込む場合に波カッコが使えるようになったことです。
次に示すのは、EExのコーディング例です:
<div class="<%= @k %>">
<%= @score %>
</div>
これがHEExではこうなります:
<div class={@k}>
<%= @score %>
</div>
従来の書き方には角カッコが入れ子になるため読みづらいという欠点がありました。また、新しい書き方の方が短く簡潔です。
関数コンポーネント
HEExの第2の特徴は、関数コンポーネントというものが加わったことです。
EExでは、テンプレート square.html.eex
を別のテンプレートに埋め込む時、次のように記述していました:
<%= render "square.html", letter: "A", bg_color: "bg-red-600" %>
HEExでは、テンプレート square.html.heex
を別のテンプレートに埋め込む場合、次のように書くことになります:
<.square letter="A" bg_color="bg-red-600" />
Phoenix 1.7 で render
関数を用いるとエラーが発生します。この関数を引き続き使い続けたい場合は、mix.exs
の関数 deps
で phoenix_view というライブラリを組み込む必要があります。
{:phoenix_view, "~> 2.0"}
~H
シギル
動画では触れませんでしたが、テンプレート square.html.heex
のコードを ~H
シギルを用いて関数の中に埋め込むことができます。
例えば、lib/daimon002_web/controllers/page_html
ディレクトリに square.html.heex
という名前のファイルがあり、それが次のような内容を持っていたとします:
<div class={"w-24 h-24 #{@bg_color} text-white flex justify-center items-center"}>
<%= @letter %>
</div>
また、同じディレクトリに page_html.ex
というファイルがあり、次のように Daimon002Web.PageHTML
モジュールが定義されていたとします:
defmodule Daimon002Web.PageHTML do
use Daimon002Web, :html
embed_templates "page_html/*"
end
この時、square.html.heex
を削除して、次のように書き換えることができます。
defmodule Daimon002Web.PageHTML do
use Daimon002Web, :html
embed_templates "page_html/*"
defp square(assigns) do
~H"""
<div
class={"w-24 h-24 #{@bg_color} text-white flex justify-center items-center"}>
<%= @letter %>
</div>
"""
end
end
関数コンポーネントを Daimon002Web.PageHTML
モジュールの関数 square/1
として表現することと、square.html.heex
というHEExテンプレートして表現することは同値です。そのため、上記のような書き換えをした時に、square.html.heex
を削除しないと例外 CompileError
が発生し、次のようなエラーメッセージがログに出力されます。
== Compilation error in file lib/daimon002_web/controllers/page_html.ex ==
** (CompileError) lib/daimon002_web/controllers/page_html.ex: cannot compile file (errors have been logged)
lib/daimon002_web/controllers/page_html.ex:6: (module)
(elixir 1.16.1) lib/kernel/parallel_compiler.ex:428: anonymous fn/5 in Kernel.ParallelCompiler.spawn_workers/8
Compiling 1 file (.ex)
error: defp square/1 already defined as def in lib/daimon002_web/controllers/page_html.ex:4
│
6 │ defp square(assigns) do
│ ^
│
└─ lib/daimon002_web/controllers/page_html.ex:6:8
Discussion