Fayland 林 > Book-Chinese-MasterPerlToday-0.02 > Book::Chinese::MasterPerlToday::Template

Download:
Book-Chinese-MasterPerlToday-0.02.tar.gz

Annotate this POD

View/Report Bugs
Source  

NAME ^

Book::Chinese::MasterPerlToday::Template - Template::Toolkit

DESCRIPTION ^

概念

细节语法

更多的请参考 Template::Manual::Syntax

INSERT INCLUDE PROCESS

为了更好的组织和复用代码,我们会经常将一个网页所调用的 tt 模板分为好几个。

而在一个主模版里调用外部模板,我们有好多种办法,介绍如下:

filter 过滤器

过滤器是指将一段文字传递进来,然后通过过滤器的函数,最后传递文字回去。我们将通过自定义过滤器来更清楚的了解过滤器的运作过程。

内置过滤器

Template 定义了一些常用的过滤器,我们将通过语法介绍来认识一些过滤器,更多更详细的介绍请参考 Template::Manual::Filters

    [% # 1 %]
    [% FILTER html %]
    <script language="JavaScript" type="text/javascript">
    <!--
    document.writeln("Hello, world");
    //-->
    </script>
    [% END %]

    [% # 2 %]
    [% pi = 3.1415926536 %]
    [% pi | format('%0.3f') %]

上文是两种过滤器的写法。本质上说 FILTER 和 | 是等价的。所有用 FILTER 的地方都可以用 | 来替换,反之亦然。一种是 [% FILTER html %][% END %] 一种是 [% pi | format('%0.3f') %]

[% FILTER html %][% END %] 可以写作

    [% output = BLOCK %]
    <script language="JavaScript" type="text/javascript">
    <!--
    document.writeln("Hello, world");
    //-->
    </script>
    [% END %]
    [% output FILTER html %]

两者的效果是一样的,只是 FILTER END 在某些情况下更方便和简洁。

过滤器可以在一个变量上多次使用,类如 [% output | html | truncate(30) %],这等同于 [% output = output | html %][% output | truncate(30) %], 这里我们使用了变量来接受过滤器返回的值。

自定义过滤器

我们将过滤器分为两种,一种类如 [% output FILTER html %],称之为静态过滤器;另一种为 [% pi | format('%0.3f') %] (过滤器上带参数),称之为动态过滤器。

这两种不同的过滤器有两种不同的写法。

FILTERS

    my $tt = Template->new({
        FILTERS => {
            'ucf' => \&ucf,
            'lcf' => sub { lcfirst uc shift; },
            'cut' => [ \&cut, 1 ], # our dynamic filter
        },
    });
    
    sub ucf {
        my $text = shift;
        $text = ucfirst lc $text;
        return $text;
    }
    sub cut {
        my ($context, $len) = @_;
        return sub {
            my $text = shift;
            $text = substr($text, 0, $len);
            return $text;
        }
    }

这是一种通过 Template FILTERS 而定义的过滤器。静态的过滤器通过子程序引用(或匿名子程序),第一次参数而需要过滤的文本。动态过滤器通过传递数组引用(第一参数为子程序引用,第二参数为1)。静态子程序也接受数组引用,但是第二参数为0,如 'ucf' => [ \&ucf, 0 ]

动态过滤器需要返回匿名子程序,过滤器的参数将传递进数组引用的第一个参数子程序引用,而需要过滤的文本将是返回的匿名子程序的第一参数。

测试的代码参考 eg/Template/filter.pl

    [% FILTER ucf %]
    template is great
    [% END %]
    [% lcf_text = 'template is great' %]
    [% lcf_text | lcf %]
    
    [% FILTER cut(6) %]template is great[% END %]

运行结果为

    E:\Fayland\chinese-perl-book\eg\Template>perl filter.pl
    Template is great
    tEMPLATE IS GREAT
    templa

PLUGINS

Template::Plugin::Filter

    package MyTemplate::Plugin::Filter::Textile;

    use strict;
    use warnings;
    use Template::Plugin::Filter;
    use base qw(Template::Plugin::Filter);
    use Text::Textile ();
    
    sub filter {
       my ($self, $text) = @_;
       return Text::Textile::textile($text);
    }
    
    1;

另一种过滤器的写法是通过继承 Template::Plugin::Filter

注册使用的办法有两种,如果你有很多个 MyTemplate::Plugin::Filter 你可以使用 PLUGIN_BASE 来注册。

    my $tt2 = Template->new( {
        PLUGIN_BASE => 'MyTemplate::Plugin::Filter'
    } );

如果仅仅是一个或两个的话,可以使用 PLUGINS 来注册该过滤器插件。

    my $tt2 = Template->new({
        PLUGINS => {
            Textile => 'MyTemplate::Plugin::Filter::Textile',
        },
    });

它的使用方法与普通插件类似

    [% USE Textile %]
    [% FILTER $Textile %]this is _like_ *so* *cool*[% END %]

运行参考 eg/Template/filter_plugin.pl

    E:\Fayland\chinese-perl-book\eg\Template>perl filter_plugin.pl
    <p>this is <em>like</em> <strong>so</strong> <strong>cool</strong></p>

上面的例子是静态过滤器,如果想写动态过滤器的话,可以在 package 里写 our $DYNAMIC = 1; 或在 sub init 里定义 $self->{ _DYNAMIC } = 1; 具体可以参考 Template::Plugin::Filter 文档。

如果你很熟悉写 Template 插件的话,其实你可以通过在 sub new 里调用 $context->define_filter('html2text', [ \&html2text, 1 ]); 来定义一个过滤器,而不必继承 Template::Plugin::Filter。例子可以查看 Template::Plugin::HtmlToText 的源码。

tools 工具

tpage

Template::Tools::tpage

tpage 用来测试一些简单的 tt2 语法还是比较轻快的。

比如你对 .replace("'", "\'") 是不是正确比较怀疑的话,你可以写个 test.tt2

  [%
    test = "A'A";
    test.replace("'", "\'");
  %]

通过命令行

  $> tpage test.tt2
  A'A

错误的话可以改改 test.tt2

  [%
    test = "A'A";
    test.replace("'", "\\\'");
  %]

再次运行

  $> tpage test.tt2
  A\'A

一切 OK, 用 tpage 你可以不用打开浏览器来检测你写的简单改变是不是正确的,非常节省时间。

tpage 还可以传递变量

    $> cat test.tt2
    [% test.replace("'", "\\\'"); %]
    $> tpage --define test="A'A" test.tt2
    A\'A
    $> tpage --define test="A'A'A" test.tt2
    A\'A\'A

资源

AUTHOR ^

Fayland Lam, <fayland at gmail.com>

COPYRIGHT & LICENSE ^

Copyright (c) 2009 Fayland Lam

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

syntax highlighting: