Mojolicious模板渲染(六)
一、helpers
helper是一种类似全局变量的小函数,可以在模板、应用层或者controller控制层调用:
# Template
模板
%= dumper [1, 2, 3]
# Application
应用
my $serialized = $app->dumper([1, 2, 3]);
# Controller
控制
my $serialized = $c->dumper([1, 2, 3]);
helper是可以按照调用环境进行区分的,比如说Mojolicious::Plugin::DefaultHelpers的dumper属于通用的helper可以在上述三种环境下调用。而Mojolicious::Plugin::TagHelpers中link_to,这是一个标签helper只能在html模板中调用。
%= link_to Mojolicious => 'https://mojolicious.org'
在控制器中,你也可以使用Mojolicious::Controller中的方法“helpers”来确定helper调用的条件,并确保它们不会与你现有的方法冲突。
my $serialized = $c->helpers->dumper([1, 2, 3]);
所有内置helper都可以在Mojolicious::Plugin::DefaultHelpers和Mojolicious::Plugin::TagHelpers中找到。
二、Content negotiation返回内容协商
当我们的前端页面想要返回不同的内容格式时,比如说前端浏览器希望返回json格式或者xml格式,我们可以使用Mojolicious::Plugin::DefaultHelpers中的respond_to方法来代替Mojolicious::Controller的render 方法。
最好的内容协商方式是通过GET/POST方法、stash关键字format、请求头中的Accept参数来自动确定。要更改Accept请求头或内容类型响应头的MIME类型映射,可以在Mojolicious中使用“types”方法,如下:
# /hello (Accept: application/json) -> "json"
# /hello (Accept: application/xml) -> "xml"
# /hello.json -> "json"
# /hello.xml -> "xml"
# /hello?format=json -> "json"
# /hello?format=xml -> "xml"
$c->respond_to(
json => {json => {hello => 'world'}},
xml => {text => '<hello>world</hello>'}
);
回调函数可以用于过于复杂而无法放入单个渲染调用的内容:
$c->respond_to(
json => {json => {hello => 'world'}},
html => sub {
#回调函数
$c->content_for(head => '<meta name="author" content="sri">');
$c->render(template => 'hello', message => 'world')
}
);
如果找不到可行的表示,则使用any回退,或者自动呈现一个空的204响应:
# /hello (Accept: application/json) -> "json"
# /hello (Accept: text/html) -> "html"
# /hello (Accept: image/png) -> "any"
# /hello.json -> "json"
# /hello.html -> "html"
# /hello.png -> "any"
# /hello?format=json -> "json"
# /hello?format=html -> "html"
# /hello?format=png -> "any"
$c->respond_to(
json => {json => {hello => 'world'}},
html => {template => 'hello', message => 'world'},
any => {text => '', status => 204}
);
对于更复杂的协商逻辑,你也可以使用Mojolicious::Plugin::DefaultHelpers中的helper “accepts”:
# /hello -> "html"
# /hello (Accept: text/html) -> "html"
# /hello (Accept: text/xml) -> "xml"
# /hello (Accept: text/plain) -> undef
# /hello.html -> "html"
# /hello.xml -> "xml"
# /hello.txt -> undef
# /hello?format=html -> "html"
# /hello?format=xml -> "xml"
# /hello?format=txt -> undef
if (my $format = $c->accepts('html', 'xml')) {
...
}