我可以使用 Mojolicious 构建静态站点吗?

编程入门 行业动态 更新时间:2024-10-21 04:14:59
本文介绍了我可以使用 Mojolicious 构建静态站点吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

是否可以使用 Mojolicious 模板系统来构建静态网站?

Is it possible to use the Mojolicious template system to build a static website?

我正在尝试使用这样的(骨架)脚本:

I'm trying to use a (skeleton) script like this:

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

但是我收到一个错误消息:

However I get an error nessage:

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'; 一切都很好,但能够重用片段和布局才是重点.

Obviously, if I omit % layout 'default'; all is good, but being able to reuse snippets and layout is the whole point.

我知道我可以使用模板工具包或其他一些模板系统,但我想尽可能避免使用多个系统的认知摩擦.

I know I could use Template Toolkit or some other templating system, but I want to avoid the cognitive friction of using multiple systems if at possible.

我也知道我可以将 mojolicious 作为服务器启动并获取所有页面,但这似乎有点矫枉过正.

I'm also aware that I could start up mojolicious as a server and wget all the pages, but it seems overkill.

这里有什么帮助吗?

推荐答案

您可以在 Mojolicious Web 框架之外使用 Mojo 模板——我过去常常这样做来为我的博客呈现静态页面.但是,默认情况下 Mojo::Template 不附带普通帮助程序.相反,Mojolicous 的其余部分将变量和帮助程序注入模板.

You can use Mojo templates outside of the Mojolicious web framework – I used to do that to render static pages for my blog. However, the Mojo::Template does not come with the normal helpers by default. Instead, the rest of Mojolicous injects variables and helpers into the template.

对于我的博客,我决定实现我自己的帮助系统.我将在本答案的其余部分描述我的解决方案.Mojo 可能在此期间发生了变化,可能更喜欢一些不同的解决方案.

For my blog, I decided to implement my own helper system. I'll describe my solution in the rest of this answer. Mojo may have changed in the meantime, and may prefer some different solution.

我将模板建模为一对 stash 引用和 Mojo::Template 对象.每个模板都编译成自己的包.稍后,我们可以将临时值注入 stash 引用并将值传递给外部.帮助器是特定存储引用的闭包,因此它可以在不使用显式参数的情况下访问这些值.

I modelled a template as a pair of a stash reference and the Mojo::Template object. Each Template is compiled into its own package. Later, we can inject temporary values into the stash reference and communicate values to the outside. A helper is a closure of a specific stash ref, so it can access these values without using an explicit parameter.

以下是模板的编译方式:

Here's how templates are compiled:

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 帮助器,它将请求的布局写入存储变量:

Here is a layout helper that writes the requested layout into a stash variable:

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 }; }; },

outer sub 仅用于关闭$stash_ref,并在上面的模板编译期间执行.

The outer sub is only used to close over the $stash_ref, and is executed during template compilation above.

为了渲染模板,我们提供临时存储值,然后处理 Mojo::Template.如果 stash 包含布局参数,我们将递归渲染布局模板,并将当前模板的输出作为内容:

To render the template, we supply temporary stash values, then process the Mojo::Template. If the stash contains a layout argument, we recurse to render the layout template with the current template's output as content:

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 的所有其余部分(特别是控制器,对于静态站点毫无意义).一段时间后,我切换到了一个不同的模板引擎,该引擎支持开箱即用的模板继承,没有如此广泛的解决方法.

This approach is not terribly elegant, but it works without having to pull in all the rest of Mojolicious (particularly controllers, which are pointless for a static site). Some time later I switched to a different template engine that supports template inheritance out of the box, without such extensive workarounds.

更多推荐

我可以使用 Mojolicious 构建静态站点吗?

本文发布于:2023-11-05 08:02:18,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1560305.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:可以使用   静态   站点   Mojolicious

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!