Templates Erlydtl:有没有办法在模板中呈现记录列表?
例如,我有:Templates Erlydtl:有没有办法在模板中呈现记录列表?,templates,erlang,Templates,Erlang,例如,我有: -record(usr,{name,email}). ... Usr1 = #usr{name="John", email="john@host.com"}, Usr2 = #usr{name="Jane", email="jane@host.com"}, Usr3 = #usr{name="Alex", email="alex@host.com"}, {ok, Result} = template_dtl:render([{users, [Usr1, Usr2, Usr3]}])
-record(usr,{name,email}).
...
Usr1 = #usr{name="John", email="john@host.com"},
Usr2 = #usr{name="Jane", email="jane@host.com"},
Usr3 = #usr{name="Alex", email="alex@host.com"},
{ok, Result} = template_dtl:render([{users, [Usr1, Usr2, Usr3]}]),
...
我想像这样使用它:
{% block content %}
{% for user in users %}
<a href="mailto:{{user.email}}">Send mail to {{user.name}}</a>
{% endfor %}
{% endblock %}
{%block content%}
{users%%中的用户为%s}
{%endfor%}
{%endblock%}
有人遇到过同样的问题吗?记录是元组之上的语法糖
Usr1
、Usr2
和Usr3
只是元组,准确地说:
Usr1 = {usr, "John", "john@host.com"},
Usr2 = {usr, "Jane", "jane@host.com"},
Usr3 = {usr, "Alex", "alex@host.com"}.
模板不知道如何解释这些记录,因为它在编译时不知道记录定义
你的问题有三种解决方案。在所有情况下,模板都是相同的,您应该像以前那样编写user.email
和user.name
教erlydtl你的记录
record\u info
compile选项正是为了告诉erlydtl模板变量中使用的记录
erlydtl:compile_template(Template, TemplateModuleName, [{record_info, [{usr, record_info(fields, usr)}]).
缺点是您可能不会自己调用erlydtl:compile*
,因此添加record\u info
选项可能会很困难。此外,调用此函数的代码段必须知道记录定义,您可能必须将其移动到.hrl
文件中
将记录转换为dict:dict()、proplist()或gb_trees:tree()
这就是他们评论中所暗示的。为此,还可以使用编译时函数record_info/2
。最简单的是proplist()
表单:
lists:zip(record_info(fields, usr), tl(tuple_to_list(Usr1))).
tuple-to-list(Usr1)
计算结果为[usr,“John”john@host.com“]
,而记录信息(字段,usr)
等于[姓名,电子邮件]
将数据封装在模块中
对于使用公共访问器(user.name
)捕获数据结构来说,记录并不是很好,因为它们可以更好地在给定模块的本地维护,因为这使得代码更新更加容易。或者,您可以定义一个模块(称为usr
或app\u user
,但不是user
,因为这样的模块已经存在)来导出name/1
和email/1
访问者
Erlydtl magic在此基于以前称为参数化模块的功能,更准确地说,它能够使用元组(而不是原子)作为模块名称来调用函数。您实际上不需要参数化模块,只需传递与现有模块匹配的元组即可
例如,您的app\u用户
模块可能如下所示:
-module(app_user).
-export([new/2, name/1, email/1]).
-record(?MODULE, {name :: string(), email :: string()}). % private to this module.
-type app_user() :: #?MODULE{}.
-spec new(string(), string()) -> app_user().
new(Name, Email) -> #?MODULE{name = Name, email = Email}.
-spec name(app_user()) -> string().
name(#?MODULE{name = Name}) -> Name.
-spec email(app_user()) -> string().
email(#?MODULE{email = Email}) -> Email.
(?模块
用于代替app\u user
,因为这仅在记录名称与模块名称匹配时有效,即使重命名模块,此代码也有效)
然后,在代码中,而不是:
Usr1 = #usr{name = "John", email = "john@host.com"}
你会写:
Usr1 = app_user:new("John", "john@host.com").
Usr1只是一个记录,或者更准确地说是元组:
{app_user, "John", "john@host.com"}.
然而,Erlydtl将能够直接处理
Usr1
。它将被认为是一个参数化的模块,因为<代码> AppHythux<代码>作为一个模块存在(它是上面的模块)。因此,在模板呈现期间,它将调用app\u user:name/1
和app\u user:email/1
访问器函数,将整个记录传递给它们。记录是元组顶部的语法糖Usr1
、Usr2
和Usr3
只是元组,准确地说:
Usr1 = {usr, "John", "john@host.com"},
Usr2 = {usr, "Jane", "jane@host.com"},
Usr3 = {usr, "Alex", "alex@host.com"}.
模板不知道如何解释这些记录,因为它在编译时不知道记录定义
你的问题有三种解决方案。在所有情况下,模板都是相同的,您应该像以前那样编写user.email
和user.name
教erlydtl你的记录
record\u info
compile选项正是为了告诉erlydtl模板变量中使用的记录
erlydtl:compile_template(Template, TemplateModuleName, [{record_info, [{usr, record_info(fields, usr)}]).
缺点是您可能不会自己调用erlydtl:compile*
,因此添加record\u info
选项可能会很困难。此外,调用此函数的代码段必须知道记录定义,您可能必须将其移动到.hrl
文件中
将记录转换为dict:dict()、proplist()或gb_trees:tree()
这就是他们评论中所暗示的。为此,还可以使用编译时函数record_info/2
。最简单的是proplist()
表单:
lists:zip(record_info(fields, usr), tl(tuple_to_list(Usr1))).
tuple-to-list(Usr1)
计算结果为[usr,“John”john@host.com“]
,而记录信息(字段,usr)
等于[姓名,电子邮件]
将数据封装在模块中
对于使用公共访问器(user.name
)捕获数据结构来说,记录并不是很好,因为它们可以更好地在给定模块的本地维护,因为这使得代码更新更加容易。或者,您可以定义一个模块(称为usr
或app\u user
,但不是user
,因为这样的模块已经存在)来导出name/1
和email/1
访问者
Erlydtl magic在此基于以前称为参数化模块的功能,更准确地说,它能够使用元组(而不是原子)作为模块名称来调用函数。您实际上不需要参数化模块,只需传递与现有模块匹配的元组即可
例如,您的app\u用户
模块可能如下所示:
-module(app_user).
-export([new/2, name/1, email/1]).
-record(?MODULE, {name :: string(), email :: string()}). % private to this module.
-type app_user() :: #?MODULE{}.
-spec new(string(), string()) -> app_user().
new(Name, Email) -> #?MODULE{name = Name, email = Email}.
-spec name(app_user()) -> string().
name(#?MODULE{name = Name}) -> Name.
-spec email(app_user()) -> string().
email(#?MODULE{email = Email}) -> Email.
(?模块
用于代替app\u user
,因为这仅在记录名称与模块名称匹配时有效,即使重命名模块,此代码也有效)
然后,在代码中,而不是:
Usr1 = #usr{name = "John", email = "john@host.com"}
你会写:
Usr1 = app_user:new("John", "john@host.com").
Usr1只是一个记录,或者更准确地说是元组:
{app_user, "John", "john@host.com"}.
然而,Erlydtl将能够直接处理Usr1
。它将被认为是一个参数化的模块,因为<代码> AppHythux<代码>作为一个模块存在(它是上面的模块)。因此,在模板呈现期间,它将调用app\u user:name/1
和app\u user:email/1
访问者函数,pass