查看源代码 EEx (EEx v1.16.2)

EEx 代表嵌入式 Elixir。

嵌入式 Elixir 允许您以稳健的方式将 Elixir 代码嵌入到字符串中。

iex> EEx.eval_string("foo <%= bar %>", bar: "baz")
"foo baz"

此模块提供了三个主要 API供您使用

  1. 直接评估字符串 (eval_string/3) 或文件 (eval_file/3)。这是最简单的 API,但也是最慢的,因为代码在运行时被评估,而不是预编译。

  2. 从字符串 (function_from_string/5) 或文件 (function_from_file/5) 定义函数。这允许您将模板作为函数嵌入到模块中,然后该模块将被编译。如果您在编译时可以访问模板,这是首选的 API。

  3. 将字符串 (compile_string/2) 或文件 (compile_file/2) 编译成 Elixir 语法树。这是上面两个函数使用的 API,如果您想提供自己的方法来处理已编译的模板,该 API 可供您使用。

上面的 API 支持几个选项,下面有说明。您还可以传递一个引擎来定制 EEx 代码的编译方式。

选项

此模块中的所有函数(除非另有说明)都接受与 EEx 相关的选项。它们是

  • :file - 模板中要使用的文件。默认为模板读取的给定文件,或在从字符串编译时默认为 "nofile"

  • :line - 要用作模板开始的行。默认为 1

  • :indentation - (自 v1.11.0 起)在每行新行后添加的整数。默认为 0

  • :engine - 用于编译的 EEx 引擎。默认为 EEx.SmartEngine.

  • :trim - 如果为 true,则修剪引号左右两边的空格,只要存在至少一个换行符。所有后续的换行符和空格都被删除,但保留一个换行符。默认为 false

  • :parser_options - (自:1.13.0 起)允许自定义生成的解析代码。有关可用选项,请参阅 Code.string_to_quoted/2。请注意,如果传递了 :file:line:column 选项,则会忽略这些选项。默认为 Code.get_compiler_option(:parser_options)(如果未设置,则默认为 [])。

标签

EEx 支持多个标签,如下所示

<% Elixir expression: executes code but discards output %>
<%= Elixir expression: executes code and prints result %>
<%% EEx quotation: returns the contents inside the tag as is %>
<%!-- Comments: they are discarded from source --%>

EEx 支持其他标签,这些标签可能被某些引擎使用,但默认情况下它们没有意义

<%| ... %>
<%/ ... %>

引擎

EEx 具有引擎的概念,这使您可以修改或转换从给定字符串或文件中提取的代码。

默认情况下,EEx 使用 EEx.SmartEngine,它在简单的 EEx.Engine 之上提供了一些便利。

EEx.SmartEngine

智能引擎使用 EEx 默认规则并添加 @ 结构来读取模板分配

iex> EEx.eval_string("<%= @foo %>", assigns: [foo: 1])
"1"

换句话说,<%= @foo %> 转换为

<%= {:ok, v} = Access.fetch(assigns, :foo); v %>

当模板所需变量的数量在编译时未指定时,assigns 扩展非常有用。

摘要

函数

获取 filename 并生成一个可由 Elixir 评估或编译成函数的引用表达式。

获取字符串 source 并生成一个可由 Elixir 评估或编译成函数的引用表达式。

获取 filename 并使用 bindings 评估值。

获取字符串 source 并使用 bindings 评估值。

根据给定选项对给定内容进行标记。

类型

@type column() :: non_neg_integer()
@type line() :: non_neg_integer()
@type marker() :: ~c"=" | ~c"/" | ~c"|" | []
@type metadata() :: %{column: column(), line: line()}
@type token() ::
  {:comment, charlist(), metadata()}
  | {:text, charlist(), metadata()}
  | {:expr | :start_expr | :middle_expr | :end_expr, marker(), charlist(),
     metadata()}
  | {:eof, metadata()}

函数

链接到此函数

compile_file(filename, options \\ [])

查看源代码
@spec compile_file(
  Path.t(),
  keyword()
) :: Macro.t()

获取 filename 并生成一个可由 Elixir 评估或编译成函数的引用表达式。

如果您想将 EEx 模板编译成代码,并将该代码注入到某个地方或在运行时评估它,这将非常有用。

生成的引用代码将使用模板中定义的变量,这些变量将从评估代码的上下文获取。如果您有一个像 <%= a + b %> 这样的模板,那么返回的引用代码将在评估它的上下文中的 ab 变量。请参见下面的示例。

支持的 options模块文档中 有说明。

示例

# sample.eex
<%= a + b %>

# In code:
quoted = EEx.compile_file("sample.eex")
{result, _bindings} = Code.eval_quoted(quoted, a: 1, b: 2)
result
#=> "3"
链接到此函数

compile_string(source, options \\ [])

查看源代码
@spec compile_string(
  String.t(),
  keyword()
) :: Macro.t()

获取字符串 source 并生成一个可由 Elixir 评估或编译成函数的引用表达式。

如果您想将 EEx 模板编译成代码,并将该代码注入到某个地方或在运行时评估它,这将非常有用。

生成的引用代码将使用模板中定义的变量,这些变量将从评估代码的上下文获取。如果您有一个像 <%= a + b %> 这样的模板,那么返回的引用代码将在评估它的上下文中的 ab 变量。请参见下面的示例。

支持的 options模块文档中 有说明。

示例

iex> quoted = EEx.compile_string("<%= a + b %>")
iex> {result, _bindings} = Code.eval_quoted(quoted, a: 1, b: 2)
iex> result
"3"
链接到此函数

eval_file(filename, bindings \\ [], options \\ [])

查看源代码
@spec eval_file(Path.t(), keyword(), keyword()) :: String.t()

获取 filename 并使用 bindings 评估值。

支持的 options模块文档中 有说明。

示例

# sample.eex
foo <%= bar %>

# IEx
EEx.eval_file("sample.eex", bar: "baz")
#=> "foo baz"
链接到此函数

eval_string(source, bindings \\ [], options \\ [])

查看源代码
@spec eval_string(String.t(), keyword(), keyword()) :: String.t()

获取字符串 source 并使用 bindings 评估值。

支持的 options模块文档中 有说明。

示例

iex> EEx.eval_string("foo <%= bar %>", bar: "baz")
"foo baz"
链接到此宏

function_from_file(kind, name, file, args \\ [], options \\ [])

查看源代码 (宏)

从文件内容生成函数定义。

第一个参数是生成的函数的类型 (:def:defp)。name 参数是生成的函数将具有的名称。 file 是 EEx 模板文件的路径。 args 是生成的函数将接受的参数列表。它们将在 EEx 模板中可用。

此函数在您有模板但想在模块中预编译以提高速度的情况下很有用。

支持的 options模块文档中 有说明。

示例

# sample.eex
<%= a + b %>

# sample.ex
defmodule Sample do
  require EEx
  EEx.function_from_file(:def, :sample, "sample.eex", [:a, :b])
end

# iex
Sample.sample(1, 2)
#=> "3"
链接到此宏

function_from_string(kind, name, template, args \\ [], options \\ [])

查看源代码 (宏)

从给定字符串生成函数定义。

第一个参数是生成的函数的类型 (:def:defp)。name 参数是生成的函数将具有的名称。 template 是包含 EEx 模板的字符串。 args 是生成的函数将接受的参数列表。它们将在 EEx 模板中可用。

支持的 options模块文档中 有说明。

示例

iex> defmodule Sample do
...>   require EEx
...>   EEx.function_from_string(:def, :sample, "<%= a + b %>", [:a, :b])
...> end
iex> Sample.sample(1, 2)
"3"
链接到此函数

tokenize(contents, opts \\ [])

查看源代码 (自 1.14.0 起)
@spec tokenize([char()] | String.t(), opts :: keyword()) ::
  {:ok, [token()]} | {:error, String.t(), metadata()}

根据给定选项对给定内容进行标记。

选项

  • :line - 用作行的整数。默认为 1。
  • :column - 用作列的整数。默认为 1。
  • :indentation - 指示缩进的整数。默认为 0。
  • :trim - 告诉标记器是否修剪内容。默认为 false。
  • :file - 可以是文件或字符串 "nofile"。

示例

iex> EEx.tokenize('foo', line: 1, column: 1)
{:ok, [{:text, 'foo', %{column: 1, line: 1}}, {:eof, %{column: 4, line: 1}}]}

结果

它返回 {:ok, [token]},其中 token 是以下之一

  • {:text, content, %{column: column, line: line}}
  • {:expr, marker, content, %{column: column, line: line}}
  • {:start_expr, marker, content, %{column: column, line: line}}
  • {:middle_expr, marker, content, %{column: column, line: line}}
  • {:end_expr, marker, content, %{column: column, line: line}}
  • {:eof, %{column: column, line: line}}

或在发生错误时返回 {:error, message, %{column: column, line: line}}。请注意,将来可能会添加新的标记。