我可以使用 Mojolicious 来构建静态站点吗?
Can I use Mojolicious to build a static site?
是否可以使用Mojolicious模板系统搭建静态网站?
我正在尝试使用这样的(骨架)脚本:
use Mojo::Template;
use Mojolicious::Plugin::DefaultHelpers;
use Mojolicious::Plugin::TagHelpers;
my $mt = Mojo::Template->new;
print $mt->render_file('index.html.ep');
其中index.html.ep
是这样的:
% layout 'default';
This is a foo
但是我收到一条错误消息:
String found where operator expected at index.html.ep line 1, near "layout 'default'"
(Do you need to predeclare layout?)
syntax error at index.html.ep line 1, near "layout 'default'"
1: % layout 'default';
2: This is a foo
显然,如果我省略 % layout 'default';
一切都很好,但能够重用片段和布局才是重点。
我知道我可以使用 Template Toolkit 或其他一些模板系统,但我想尽可能避免使用多个系统的认知摩擦。
我也知道我可以启动 mojolicious 作为服务器并获取所有页面,但这似乎有点过分了。
这里有什么帮助吗?
您可以在 Mojolicious 网络框架之外使用 Mojo 模板——我曾经这样做来为我的博客呈现静态页面。但是,默认情况下 Mojo::Template
不附带普通助手。相反,Mojolicous 的其余部分将变量和助手注入模板。
对于我的博客,我决定实现我自己的帮助系统。我将在本答案的其余部分描述我的解决方案。 Mojo 可能在此期间发生了变化,并且可能更喜欢一些不同的解决方案。
我将模板建模为一对 stash 引用和 Mojo::Template 对象。每个模板都被编译成自己的包。稍后,我们可以将临时值注入存储引用并将值传递给外部。助手是特定存储引用的闭包,因此它可以在不使用显式参数的情况下访问这些值。
模板的编译方式如下:
package AMON::Blog::TemplateCollection;
sub add_template($self, $name, $source) {
state $namespace_id = 0;
my $namespace = Package::Stash->new(
__PACKAGE__ . '::Namespace::' . ++$namespace_id);
my $template = Mojo::Template->new(
name => $name,
namespace => $namespace->name,
auto_escape => 1,
tag_start => '{{',
tag_end => '}}',
);
# enter the helpers into the namespace
my $stash_ref = \{};
while (my ($name, $code) = each %{ $self->helpers }) {
$namespace->add_symbol('&' . $name => $code->($stash_ref));
}
$template->parse($source);
$self->templates->{$name} = {
stash_ref => $stash_ref,
template => $template
};
return;
}
这是一个 layout
帮助程序,它将请求的布局写入存储变量:
layout => sub ($stash_ref) {
return sub ($name, %args) {
if (my $existing = $$stash_ref->{layout}) {
croak sprintf q(Can't change layout from "%s" to "%s"), $existing->{name}, $name;
}
$$stash_ref->{layout} = { name => $name, args => \%args };
};
},
外层sub仅用于关闭$stash_ref
,并在上面的模板编译期间执行。
为了呈现模板,我们提供临时存储值,然后处理 Mojo::Template。如果 stash 包含布局参数,我们递归渲染布局模板,当前模板的输出作为内容:
sub render($self, $name, %args) {
my $template = $self->templates->{$name}
// croak qq(Unknown template "$name");
my ($stash_ref, $template_object) = @$template{qw/stash_ref template/};
$$stash_ref = {
name => $name,
layout => undef,
args => \%args,
};
my $result = $template_object->process();
my $layout_args = $$stash_ref->{layout};
$$stash_ref = undef;
if (blessed $result and $result->isa('Mojo::Exception')) {
die $result;
}
if ($layout_args) {
my $name = $layout_args->{name};
my $args = $layout_args->{args};
return $self->render($name, %$args, content => $result);
}
return $result;
}
这种方法不是非常优雅,但无需引入所有其余的 Mojolicious(特别是控制器,对于静态站点毫无意义)就可以工作。一段时间后,我切换到一个不同的模板引擎,它支持开箱即用的模板继承,没有那么广泛的解决方法。
添加另一种(最小)方法来执行此操作:
use Mojolicious;
my $m = Mojolicious->new->log(Mojo::Log->new);
my $r = $m->renderer;
push @{$r->paths}, './templates';
my $c = Mojolicious::Controller->new->app($m);
my ($output, $format) = $r->render($c, { template => 'index' });
print $output
通过多个模板对此进行迭代,并将输出发送到适当命名的文件应该很简单。
如果您通过 Plack
运行 您的 Mojo 应用程序,那么您可以使用 https://metacpan.org/pod/wallflower 从您的应用程序创建静态网站。
是否可以使用Mojolicious模板系统搭建静态网站?
我正在尝试使用这样的(骨架)脚本:
use Mojo::Template;
use Mojolicious::Plugin::DefaultHelpers;
use Mojolicious::Plugin::TagHelpers;
my $mt = Mojo::Template->new;
print $mt->render_file('index.html.ep');
其中index.html.ep
是这样的:
% layout 'default';
This is a foo
但是我收到一条错误消息:
String found where operator expected at index.html.ep line 1, near "layout 'default'"
(Do you need to predeclare layout?)
syntax error at index.html.ep line 1, near "layout 'default'"
1: % layout 'default';
2: This is a foo
显然,如果我省略 % layout 'default';
一切都很好,但能够重用片段和布局才是重点。
我知道我可以使用 Template Toolkit 或其他一些模板系统,但我想尽可能避免使用多个系统的认知摩擦。
我也知道我可以启动 mojolicious 作为服务器并获取所有页面,但这似乎有点过分了。
这里有什么帮助吗?
您可以在 Mojolicious 网络框架之外使用 Mojo 模板——我曾经这样做来为我的博客呈现静态页面。但是,默认情况下 Mojo::Template
不附带普通助手。相反,Mojolicous 的其余部分将变量和助手注入模板。
对于我的博客,我决定实现我自己的帮助系统。我将在本答案的其余部分描述我的解决方案。 Mojo 可能在此期间发生了变化,并且可能更喜欢一些不同的解决方案。
我将模板建模为一对 stash 引用和 Mojo::Template 对象。每个模板都被编译成自己的包。稍后,我们可以将临时值注入存储引用并将值传递给外部。助手是特定存储引用的闭包,因此它可以在不使用显式参数的情况下访问这些值。
模板的编译方式如下:
package AMON::Blog::TemplateCollection;
sub add_template($self, $name, $source) {
state $namespace_id = 0;
my $namespace = Package::Stash->new(
__PACKAGE__ . '::Namespace::' . ++$namespace_id);
my $template = Mojo::Template->new(
name => $name,
namespace => $namespace->name,
auto_escape => 1,
tag_start => '{{',
tag_end => '}}',
);
# enter the helpers into the namespace
my $stash_ref = \{};
while (my ($name, $code) = each %{ $self->helpers }) {
$namespace->add_symbol('&' . $name => $code->($stash_ref));
}
$template->parse($source);
$self->templates->{$name} = {
stash_ref => $stash_ref,
template => $template
};
return;
}
这是一个 layout
帮助程序,它将请求的布局写入存储变量:
layout => sub ($stash_ref) {
return sub ($name, %args) {
if (my $existing = $$stash_ref->{layout}) {
croak sprintf q(Can't change layout from "%s" to "%s"), $existing->{name}, $name;
}
$$stash_ref->{layout} = { name => $name, args => \%args };
};
},
外层sub仅用于关闭$stash_ref
,并在上面的模板编译期间执行。
为了呈现模板,我们提供临时存储值,然后处理 Mojo::Template。如果 stash 包含布局参数,我们递归渲染布局模板,当前模板的输出作为内容:
sub render($self, $name, %args) {
my $template = $self->templates->{$name}
// croak qq(Unknown template "$name");
my ($stash_ref, $template_object) = @$template{qw/stash_ref template/};
$$stash_ref = {
name => $name,
layout => undef,
args => \%args,
};
my $result = $template_object->process();
my $layout_args = $$stash_ref->{layout};
$$stash_ref = undef;
if (blessed $result and $result->isa('Mojo::Exception')) {
die $result;
}
if ($layout_args) {
my $name = $layout_args->{name};
my $args = $layout_args->{args};
return $self->render($name, %$args, content => $result);
}
return $result;
}
这种方法不是非常优雅,但无需引入所有其余的 Mojolicious(特别是控制器,对于静态站点毫无意义)就可以工作。一段时间后,我切换到一个不同的模板引擎,它支持开箱即用的模板继承,没有那么广泛的解决方法。
添加另一种(最小)方法来执行此操作:
use Mojolicious;
my $m = Mojolicious->new->log(Mojo::Log->new);
my $r = $m->renderer;
push @{$r->paths}, './templates';
my $c = Mojolicious::Controller->new->app($m);
my ($output, $format) = $r->render($c, { template => 'index' });
print $output
通过多个模板对此进行迭代,并将输出发送到适当命名的文件应该很简单。
如果您通过 Plack
运行 您的 Mojo 应用程序,那么您可以使用 https://metacpan.org/pod/wallflower 从您的应用程序创建静态网站。