例如,我有:
-record(usr,{name,email}).
...
Usr1 = #usr{name="John", email="[email protected]"},
Usr2 = #usr{name="Jane", email="[email protected]"},
Usr3 = #usr{name="Alex", email="[email protected]"},
{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 %}
有人遇到过同样的问题吗?
记录是元组之上的语法糖。Usr1
,Usr2
而Usr3
只是元组,而恰恰是:
Usr1 = {usr, "John", "[email protected]"},
Usr2 = {usr, "Jane", "[email protected]"},
Usr3 = {usr, "Alex", "[email protected]"}.
该模板不知道如何解释这些记录,因为它不知道在编译时的记录定义。
有三种解决方案来解决您的问题。在所有情况下,模板都是相同的,您应该像以前那样编写user.email
和编写user.name
。
record_info
编译选项的确切含义是告诉erlydtl有关模板变量中使用的记录。
erlydtl:compile_template(Template, TemplateModuleName, [{record_info, [{usr, record_info(fields, usr)}]).
缺点是您可能不会自称erlydtl:compile*
,因此添加record_info
选项可能会很困难。此外,调用此函数的代码段必须知道您可能必须移至.hrl
文件的记录定义。
这就是坎贝尔汤在其评论中所建议的。您也可以record_info/2
为此使用编译时函数。实际上,最简单的proplist()
形式是:
lists:zip(record_info(fields, usr), tl(tuple_to_list(Usr1))).
tuple_to_list(Usr1)
评估为[usr, "John", "[email protected]"]
,而record_info(fields, usr)
等于[name, email]
。
记录对于使用公共访问器(user.name
)捕获数据结构并不是很好,因为记录可以更好地在给定模块的本地维护,因为这使代码更新变得更加容易。或者,您可以定义一个将导出和访问的模块(称为usr
或app_user
不user
存在的模块)。name/1
email/1
这里的Erlydtl魔术基于先前称为参数化模块的功能,更确切地说,是基于使用元组而不是原子作为模块名称来调用函数的功能。您实际上并不需要参数化的模块,只需传递与现有模块匹配的元组即可。
例如,您的app_user
模块可能如下所示:
-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.
(?MODULE
之所以使用它,是app_user
因为它仅在记录的名称与模块的名称匹配时才起作用,并且即使重命名模块,该代码也将起作用)。
然后,在您的代码中,而不是:
Usr1 = #usr{name = "John", email = "[email protected]"}
你会这样写:
Usr1 = app_user:new("John", "[email protected]").
Usr1只是一条记录,或更确切地说是元组:
{app_user, "John", "[email protected]"}.
尽管如此,Erlydtl仍将能够Usr1
直接进行处理。它将被视为参数化模块,作为模块app_user
存在(这是上面的模块)。因此,在模板呈现期间,它将调用app_user:name/1
和app_user:email/1
访问器函数,并向它们传递整个记录。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句