第三天 - 使用命名路由

img

我们从多年的编程中知道的一件事是,如果你不需要,你就不应该对任何东西进行硬编码。然而,太多的网络应用程序硬编码他们的网址,特别是内部网站。但是,如果你不需要怎么办?

每个 Mojolicious 路由都有自己的名字,可用于生成网址。如果您没有指定一个,则会生成一个,但您不应该依赖该名称,给它一个有意义且与您的目的相关的名称。在lite应用程序中,名称是任何默认值或回调之后的最后一个参数。 (在完整的应用程序中,它是一个属性,但我们将在另一篇文章中讨论这些内容)。

然后,当您需要一个URL而不是硬编码时,使用 url_for 或相关功能按名称生成 URL,您甚至可以根据需要传递占位符值。让我们看看它是如何工作的!

北极主页

圣诞老人从一个简单的 webapp 开始。它只有一个主页和一个页面供他和他的员工使用。由于它如此简单,他没有任何更深的路径,只有 / 用于主页和 /:name 用于员工页面。当然,我要告诉你的是一个简化,我无法向你展示圣诞老人的完整网站,原因很明显。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use Mojolicious::Lite;

get '/:name' => {template => 'staff'} => 'staff';
get '/' => {template => 'home'} => 'home';

app->start;

__DATA__

@@ staff.html.ep
<p>This is <%= ucfirst $name %>.</p>

@@ home.html.ep
<p>Welcome to The North Pole!</p>

<p>
Say hi to <%= link_to 'Santa' => staff => {name => 'santa'} %>
and <%= link_to 'Rudolph' => staff => {name => 'rudolph'} %>.
</p>

我们可以看到 link_to 使用路由名称生成链接标记。第一个参数是链接将显示的文本。以下参数按名称和占位符值构建URL。返回实际上是一个 Mojo::URL,所以如果你需要添加其他东西,比如查询参数,那么可以在之后完成。

改变路由

一切都很好,直到有一天圣诞老人决定要展示一些年度新玩具。问题是他没有为此计划他的网址。他可以保留所有现有的并添加一个特殊的套管/玩具路线,但这样看起来很傻。他真正需要做的是移动所有员工页面以保持网址一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
use Mojolicious::Lite;

get '/toy/:toy_name' => {template => 'toy'} => 'toy';
get '/meet/:name' => {template => 'staff'} => 'staff';
get '/' => {template => 'home'} => 'home';

app->start;

__DATA__

@@ toy.html.ep
<p>Look at this amazing <%= $toy_name %>.</p>

@@ staff.html.ep
<p>This is <%= ucfirst $name %>.</p>

@@ home.html.ep
<p>Welcome to The North Pole!</p>

<p>
Say hi to <%= link_to 'Santa' => staff => {name => 'santa'} %>
and <%= link_to 'Rudolph' => staff => {name => 'rudolph'} %>.
</p>

<p>
And just wait until you see our amazing
<%= link_to 'new puzzle' => toy => {toy_name => 'puzzle'} %>!
</p>

因为员工页面网址是按名称生成的,所以除了路线定义外,Santa不需要更改任何内容!

路由名作为默认模板名

我还应该提一件事。我本可以用更少的代码实际制作前面的例子。如果路由没有显式呈现某些内容,它将检查是否存在路径名称的模板。这是一些人喜欢并且可能使路由定义看起来像这样的快捷方式:

1
2
3
get '/toy/:toy_name' => 'toy';
get '/meet/:name' => 'staff';
get '/' => 'home';

虽然有些人欣赏这个功能,但我个人喜欢明确我想要的模板。我也想分开关注。无论如何,你可以选择你最喜欢的。毕竟,有不止一种方法可以做到这一点!