第二天 - The Stash
— 焉知非鱼在 Mojolicious 中,当处理请求并准备响应时,最重要的概念之一是“藏匿”。由于它是一个非阻塞框架,因此您的代码在处理期间不能使用全局变量来存储任何状态。如果您运行了一些其他代码,那么很容易在请求之间进行串扰。
存储是您在处理信息时可以存储信息的地方。它只是一个简单的哈希引用,它附加到处理请求的控制器对象上。它与这一笔交易一起生存和死亡。
虽然你可以而且应该将它用作暂存器,但实际上还是要多得多。存储控制几乎控制了您生成的响应的每个方面。让我们仔细看看它是如何工作的
使用 Stash 渲染文本 #
在上一篇文章中,我们讨论了最简单的“Hello world”应用程序。
use Mojolicious::Lite;
get '/' => {text => 'Hello 🌍 World!'};
app->start;
虽然这是一个非常简单的工作案例,但更常见的例子就是这样
use Mojolicious::Lite;
get '/' => sub {
my $c = shift;
$c->render(text => 'Hello 🌍 World!');
};
app->start;
在此示例中,GET /请求由“动作回调”处理。回调是函数引用,打算将来调用;在这种情况下,当客户端请求进入与该类型的请求匹配时,将调用回调。
使用一个参数调用操作,称为控制器。控制器是一个对象,表示我们的应用程序与当前事务的交互。它包含一个表示事务的对象,该对象又保存请求和响应的对象。它有一些方法可用于生成响应,其中一个是渲染,您可以在上面看到。在这里,您会看到我们将呈现一些文本。
事实上,渲染的大多数参数实际上只是合并到了藏匿处。实际上,上面的例子是相同的
use Mojolicious::Lite;
get '/' => sub {
my $c = shift;
$c->stash(text => 'Hello 🌍 World!');
$c->render;
};
app->start;
你现在看到的是,Mojolicious 看着藏匿处看看如何呈现回应。事实上,如果你不调用 render,但它有足够的信息来在 stash 中呈现响应,它就会这样做。
use Mojolicious::Lite;
get '/' => sub {
my $c = shift;
$c->stash(text => 'Hello 🌍 World!');
};
app->start;
Stash Defaults #
在上面的示例中,我们了解了如何在控制响应的请求期间设置存储值。请记住,只有在请求进入时才会调用动作回调。但是,我们需要等待理解如何响应它的请求没有什么特别之处。
在 Mojolicious 中,在建立路由时,我们还可以指定一些默认值以添加到每个请求的存储中(除非它们被更改)。这些默认值作为路径构造函数 get
的哈希引用传递。
use Mojolicious::Lite;
get '/' => {text => 'Hello 🌍 World!'} => sub {
my $c = shift;
};
app->start;
但是现在我们的行动没有做任何事情,所以我们根本不需要它,我们回到原来的例子。
use Mojolicious::Lite;
get '/' => {text => 'hello 🌍 world!'};
app->start;
使用占位符 #
我们可以进一步展示这个例子,并展示如何制作一个更有趣的问候语应用程序,这一次是一个名字。
use Mojolicious::Lite;
get '/:name' => sub {
my $c = shift;
my $name = $c->stash('name');
$c->stash(text => "Hello $name");
};
app->start;
在这里,我们看到占位符值被合并到存储中。然后,我们可以使用它们来呈现更个性化的响应。如果您在浏览器中启动服务器并请求/ Joel,您应该会看到一个问候我的应用程序,或者您可以使用您的名字进行操作。
如果您尝试请求/但是,您将获得404,未找到。如果没有占位符的值,路由器不希望处理此请求,因此它假定您需要一些其他路由来处理它。虽然我们可以像之前那样为/定义另一个,但我们可以通过恢复默认值来同时执行这两个操作。
use Mojolicious::Lite;
get '/:name' => {name => '🌍 world!'} => sub {
my $c = shift;
my $name = $c->stash('name');
$c->stash(text => "hello $name");
};
app->start;
现在路由器知道名称的默认值应该是什么,它现在可以处理/以及/ santa!
在模板中隐藏值 #
模板中也提供了简单的隐藏值,即只有一个单词(没有标点符号)的隐藏值。以下是使用“内联模板”的上一个示例。
use Mojolicious::Lite;
get '/:name' => {name => '🌍 world!'} => sub {
my $c = shift;
$c->stash(inline => 'hello <%= $name %>');
};
app->start;
或者如果你让我使用一个概念而不完全介绍它,这里是你脚本数据部分的模板。
use Mojolicious::Lite;
get '/:name' => {name => '🌍 world!'} => sub {
my $c = shift;
$c->render('hello');
};
app->start;
__DATA__
@@ hello.html.ep
hello <%= $name %>
在后者中,您将看到仅使用一个参数调用render的第一个示例。当使用奇数个参数调用它时,第一个是模板的标识符(名称)。这与stashing template =>‘hello’相同,您甚至可以在路由默认值中执行此操作。
特殊/保留的隐藏键 #
所以可能有一些人问“所以文本藏匿值控制渲染的一部分,名称藏匿值是否可以做任何事情?”不,只有少数隐藏值具有特殊含义,它们记录在stash方法本身上。那些键是
- action
- app
- cb
- controller
- data
- extends
- format
- handler
- inline
- json
- layout
- namespace
- path
- status
- template
- text
- variant
此外,所有键如 mojo.*
都保留供内部使用。这些值中的大多数在路由,模板或渲染中都很有用。
您已经看过 text
,它通过 utf8 编码来呈现字符串。要以二进制格式(或仅使用 utf8 编码的文本)呈现数据,请使用 data
键。这两个以及模板都将使用content-type text/html
进行渲染。要使用不同的东西,可以使用 format
键指定它。
use Mojolicious::Lite;
get '/' => {text => 'hello 🌍 world!', format => 'txt'};
app->start;
其他人都有意义,其中一些你可以自己解决,但这篇文章已经持续了很长时间。那些人将不得不等待另一天。