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')) {
  ...
}

标签