在没有插件的情况下调用模板工具包中的外部子程序和模块?

发布于 2024-08-01 13:10:03 字数 537 浏览 6 评论 0原文

我试图在 Template Toolkit .tt 文件中调用外部 Perl 模块。 我想使用的模块是Util,我想调用Util::prettify_date。 我能够使用 Template Toolkit 的插件接口包含此模块:我设置了加载、新建和错误函数(如下所述:http://template-toolkit.org/docs/modules/Template/Plugin.html),并使用 [% USE Util %].

这工作正常,但我想知道是否有一种方法可以在 Template Toolkit 中使用 Perl 模块,而无需对它们进行插件化。 制作插件的主要问题是我必须使 Util 中的所有函数都面向对象(即接受 $self 作为第一个参数),这实际上没有意义。

I am trying to call an outside Perl module in a Template Toolkit .tt file. The module I want to use is Util, and I want to call Util::prettify_date. I was able to include this module using Template Toolkit's plugin interface: I set up the load, new, and error function (as described here: http://template-toolkit.org/docs/modules/Template/Plugin.html), and include it using [% USE Util %].

This works fine, but I was wondering if there's a way to USE Perl modules in Template Toolkit without having to plugin-ify them. The main issue with making plugins is that I have to make all the functions in Util object-oriented (ie. accepts $self as first argument), which doesn't really make sense.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

路弥 2024-08-08 13:10:03

您还可以将函数(即子例程)传递给模板,如下所示:

use strict;
use warnings;
use List::Util ();
use Template;

my $tt = Template->new({
    INCLUDE_PATH  => '.',
});

$tt->process( 'not_plugin.tt', { 
    divider    => sub { '='  x  $_[0]         },
    capitalize => sub { ucfirst $_[0]         },
    sum        => sub { List::Util::sum( @_ ) },
});

not_plugin.tt

[% divider( 40 ) %]
Hello my name is [% capitalize( 'barry' ) %], how are u today?
The ultimate answer to life is [% sum( 10, 30, 2 ) %]
[% divider( 40 ) %]

将产生这个:

========================================
Hello my name is Barry, how are u today?
The ultimate answer to life is 42
========================================

You can also pass functions (ie. subroutines) to template like this:

use strict;
use warnings;
use List::Util ();
use Template;

my $tt = Template->new({
    INCLUDE_PATH  => '.',
});

$tt->process( 'not_plugin.tt', { 
    divider    => sub { '='  x  $_[0]         },
    capitalize => sub { ucfirst $_[0]         },
    sum        => sub { List::Util::sum( @_ ) },
});

not_plugin.tt

[% divider( 40 ) %]
Hello my name is [% capitalize( 'barry' ) %], how are u today?
The ultimate answer to life is [% sum( 10, 30, 2 ) %]
[% divider( 40 ) %]

will produce this:

========================================
Hello my name is Barry, how are u today?
The ultimate answer to life is 42
========================================
蓬勃野心 2024-08-08 13:10:03

您是否尝试过在 < 中使用该模块code>[% PERL %] 块?

现在,我个人会编写一个插件,在摆脱第一个后将 MyOrg::Plugin::Util->prettify_date 中继到 Util::prettify_date争论。 您也可以自动创建这些方法:

my @to_proxy = qw( prettify_date );

sub new {
    my $class = shift;

    {
        no strict 'refs';
        for my $sub ( @to_proxy) {
            *{"${class}::${sub}"} = sub {
                my $self = shift;
                return "My::Util::$sub"->( @_ );
            }
        }
    }
    bless {} => $class;
}

Have you tried useing the module in a [% PERL %] block?

Now, I personally would write a plugin which relays, say, a MyOrg::Plugin::Util->prettify_date to Util::prettify_date after getting rid of the first argument. You can automate the creation of these methods as well:

my @to_proxy = qw( prettify_date );

sub new {
    my $class = shift;

    {
        no strict 'refs';
        for my $sub ( @to_proxy) {
            *{"${class}::${sub}"} = sub {
                my $self = shift;
                return "My::Util::$sub"->( @_ );
            }
        }
    }
    bless {} => $class;
}
痕至 2024-08-08 13:10:03

实现此目的的最简单、最危险的方法是使用 [% PERL %] 块并强制在 main 命名空间中进行计算。

[% PERL %]
package main;
# You can now use any variables and subroutines as though this were in the main namespace
[% END %]

这是必要的,因为 [% PERL %] 块是 在隔离的 Template::Perl 包命名空间中进行评估,您将使用 package main 覆盖该命名空间。

危险来自于您的模板能够

The simplest, most dangerous way to accomplish this is to use a [% PERL %] block and force the evaluation to occur in the main namespace.

[% PERL %]
package main;
# You can now use any variables and subroutines as though this were in the main namespace
[% END %]

This is necessary because the [% PERL %] block is evaluated in an isolated Template::Perl package namespace, which you are overriding with package main

The danger comes from your template being able to write into the main namespace in addition to reading from it, which can lead to some interesting debug.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文