Packages

Exeex is an Elixir template engine that provides macro, include and inheritance functions. It allows you to create reusable templates with dynamic content, making it easier to manage and maintain your views in Elixir applications.

Current section

Files

Jump to
exeex lib exeex.ex
Raw

lib/exeex.ex

defmodule ExEEx do
@moduledoc """
Documentation for ExEEx.
"""
def adapter() do
Application.get_env(:exeex, :adapter, ExEEx.Adapter.FileStorage)
end
@doc """
Render template file.
## Examples
iex> ExEEx.render("test/templates/hello.txt", val: "world")
"Hello, world!\\n"
iex> ExEEx.render("test/templates/main.txt")
"This is header\\n---\\nThis is body\\n---\\nThis is footer\\n\\n"
iex> ExEEx.render("test/templates/main.txt", [{"foo", 3}])
** (ExEEx.TemplateError) expected keywords as template parameters
"""
def render(filename, params \\ [])
def render(%ExEEx.Template{code: code}, params) when is_list(params) do
if not Keyword.keyword?(params) do
raise ExEEx.TemplateError, message: "expected keywords as template parameters"
end
{result, _binding} = Code.eval_quoted(code, params)
result
end
def render(filename, params) when is_binary(filename) and is_list(params) do
compile(filename)
|> render(params)
end
@doc """
Render template string.
## Examples
iex> ExEEx.render_string("Hello, world!")
"Hello, world!"
iex> ExEEx.render_string("<%= include \\"test/templates/hello.txt\\" %>OK", val: "world")
"Hello, world!
OK"
iex> ExEEx.render_string("<%= block \\"header\\" do %>This is default header<% end %>")
"This is default header"
iex> ExEEx.render_string("<%= block \\"test\\" %>")
""
iex> ExEEx.render_string("<%= block invalid %>")
** (ExEEx.TemplateError) block name should be a string literal: nofile:1.5
"""
def render_string(template, params \\ []) when is_list(params) do
compile_string(template)
|> render(params)
end
@doc """
Compile template file.
## Examples
iex> ExEEx.compile("test/templates/hello.txt").name
"hello.txt"
"""
def compile(filename, opts \\ []) when is_binary(filename) do
file_path = adapter().expand_path(filename)
adapter().read(file_path)
|> compile_string(Keyword.put(opts, :file, file_path))
end
@doc """
Compile template file.
## Examples
iex> ExEEx.compile_string("Hello, world!").name
:nofile
"""
def compile_string(source, opts \\ []) when is_binary(source) do
{dir, name} =
with nil <- Keyword.get(opts, :file) do
#
# インメモリの場合、現在のディレクトリ
#
{adapter().expand_path("."), :nofile}
else
file ->
# 絶対パスに変換
file_path = adapter().expand_path(file)
#
# ファイルパスが渡されている場合、ディレクトリとベース名に分割
#
ExEEx.Utils.split_path(file_path)
end
file_name = to_string(name)
opts =
opts
|> Keyword.put(:file, file_name)
|> Keyword.put(:dir, dir)
|> Keyword.put(:includes, [])
|> Keyword.put(:engine, ExEEx.Engine)
ExEEx.Engine.BlockStack.init()
{code, _} =
EEx.compile_string(source, opts)
|> ExEEx.Engine.subst_blocks(file_name)
%ExEEx.Template{
code: code,
path: dir,
name: name
}
end
end