查看源代码 Phoenix.Template (phoenix_template v1.0.4)

模板是编译成 Elixir 代码的标记语言。

此模块提供了从磁盘加载和编译模板的函数。标记语言通过引擎编译成 Elixir 代码。请参阅 Phoenix.Template.Engine

在实践中,开发者很少直接使用 Phoenix.Template。相反,Phoenix.ViewPhoenix.LiveView 等库将其用作构建块。

自定义模板引擎

Phoenix 支持自定义模板引擎。引擎告诉 Phoenix 如何将模板路径转换为引用的表达式。有关自定义引擎需要实现的 API 的更多信息,请参阅 Phoenix.Template.Engine

定义模板引擎后,您可以通过模板引擎选项告诉 Phoenix 关于它

config :phoenix, :template_engines,
  eex: Phoenix.Template.EExEngine,
  exs: Phoenix.Template.ExsEngine

格式编码器

除了模板引擎之外,Phoenix 还有格式编码器的概念。格式编码器按格式工作,负责将给定格式编码为字符串。例如,在渲染 JSON 时,您的模板可能会返回一个普通的 Elixir 映射。然后调用 JSON 格式编码器将其转换为 JSON。

格式编码器必须导出一个名为 encode_to_iodata!/1 的函数,该函数接收渲染工件并返回 iodata。

可以通过格式编码器选项添加新的编码器

config :phoenix_template, :format_encoders,
  html: Phoenix.HTML.Engine

概要

函数

确保 __mix_recompile__?/0 将被定义。

为给定 root 中的每个模板编译一个函数。

一个将模板嵌入为函数的便利宏。

返回一个关键字列表,其中包含所有模板引擎扩展名,后跟它们的模块。

返回给定模板根目录中的所有模板路径。

返回给定模板的格式编码器。

返回给定根目录中所有模板路径的哈希值。

渲染模板并返回 iodata。

类型

函数

确保 __mix_recompile__?/0 将被定义。

链接到此宏

compile_all(converter, root, pattern \\ "*", engines \\ nil)

查看源代码 (宏)

为给定 root 中的每个模板编译一个函数。

converter 是一个匿名函数,它接收模板路径并返回函数名(作为字符串)。

例如,要编译给定目录中的所有 .eex 模板,您可以执行以下操作

Phoenix.Template.compile_all(
  &(&1 |> Path.basename() |> Path.rootname(".eex")),
  __DIR__,
  "*.eex"
)

如果目录包含名为 foo.eexbar.eex 的模板,它们将被编译成函数 foo/1bar/1,它们接收模板 assigns 作为参数。

您可以选择传递一个引擎的关键字列表。如果给出了列表,我们将仅查找和编译此引擎子集。如果没有传递 (nil),则使用 engines/0 返回的默认列表。

链接到此宏

embed_templates(pattern, opts \\ [])

查看源代码 (宏)

一个将模板嵌入为函数的便利宏。

此宏是在更通用的 compile_all/3 功能之上构建的。

选项

  • :root - 要嵌入文件的根目录。默认为当前模块的目录 (__DIR__)
  • :suffix - 要附加到嵌入函数名称的字符串值。默认情况下,函数名称将是模板文件名称,不包括格式和引擎。

可以使用通配符模式来选择目录树中的所有文件。例如,想象一个目录列表

 pages
    about.html.heex
    sitemap.xml.eex

然后将模板嵌入到您的模块中

defmodule MyAppWeb.Renderer do
  import Phoenix.Template, only: [embed_templates: 1]
  embed_templates "pages/*"
end

现在,您的模块将具有 about/1sitemap/1 函数。请注意,不同格式的函数被嵌入。如果您想区分它们,您可以给出更具体的模式

defmodule MyAppWeb.Emails do
  import Phoenix.Template, only: [embed_templates: 2]

  embed_templates "pages/*.html", suffix: "_html"
  embed_templates "pages/*.xml", suffix: "_xml"
end

现在函数将是 about_htmlsitemap_xml

@spec engines() :: %{required(atom()) => module()}

返回一个关键字列表,其中包含所有模板引擎扩展名,后跟它们的模块。

链接到此函数

find_all(root, pattern \\ "*", engines \\ engines())

查看源代码
@spec find_all(root(), pattern :: String.t(), %{required(atom()) => module()}) :: [
  path()
]

返回给定模板根目录中的所有模板路径。

链接到此函数

format_encoder(format)

查看源代码
@spec format_encoder(format :: String.t()) :: module() | nil

返回给定模板的格式编码器。

链接到此函数

hash(root, pattern \\ "*", engines \\ engines())

查看源代码
@spec hash(root(), pattern :: String.t(), %{required(atom()) => module()}) :: binary()

返回给定根目录中所有模板路径的哈希值。

由 Phoenix 用于检查给定根路径是否需要重新编译。

链接到此函数

module_to_template_root(module, base, suffix)

查看源代码
此函数已弃用。使用 Phoenix.View.module_to_template_root/3。
链接到此函数

render(module, template, format, assigns)

查看源代码

从模块渲染模板。

对于名为 MyApp.FooHTML 的模块和模板“index.html.heex”,它将

  • 首先尝试调用 MyApp.FooHTML.index(assigns)

  • 然后回退到 MyApp.FooHTML.render("index.html", assigns)

  • 否则引发异常

它期望 HTML 模块、模板作为字符串、格式和一组分配。

请注意,此函数返回模板的内部表示。如果您想要编码的模板作为结果,请改用 render_to_iodata/4

示例

Phoenix.Template.render(YourApp.UserView, "index", "html", name: "John Doe")
#=> {:safe, "Hello John Doe"}

分配

分配是指用户数据,这些数据将在模板中可用。但是,分配下有一些键由 Phoenix 特别处理,它们是

  • :layout - 告诉 Phoenix 将渲染的结果包装在给定的布局中。请参阅下一节

布局

可以使用 :layout 选项在其他模板中渲染模板。 :layout 接受一个元组,形式为 {LayoutModule, "template.extension"}

要进入布局的模板将被放置在 @inner_content 分配中

<%= @inner_content %>
链接到此函数

render_to_iodata(module, template, format, assign)

查看源代码

渲染模板并返回 iodata。

链接到此函数

render_to_string(module, template, format, assign)

查看源代码

将模板渲染为字符串。

链接到此函数

template_path_to_name(path, root)

查看源代码
此函数已弃用。使用 Phoenix.View.template_path_to_name/3。