Perl: Alternatives to template toolkit

后端 未结 5 901
梦毁少年i
梦毁少年i 2021-01-30 18:25

I have been using template toolkit for extending an existing domain specific language(verilog) for over 3 years now. While overall I am happy with it, the major irritant is that

相关标签:
5条回答
  • 2021-01-30 19:10

    I can suggest HTML::Template:Compiled (but note I'm the author ;-)

    It is quite compatible to HTML::Template, but has additional features.

    Support for complex data structures

    yes

    Good error reporting and debug capabilities.

    You can debug cache hits, misses, automatically add template filename to output and can use a filter "DUMP" for the current variable in stash (or any variable). If it's easy to implement I'll happily add more useful debugging.

    Stable and proven ( no alpha/beta level engines)

    I would consider it stable now, with the documented limitations/bugs (for example query())

    Extensible (plugin's etc)

    supports escape (filter) plugins and more, though the latter is not documented very well yet.

    Should not be restricted to a given language (html etc.)

    yes

    support for IF/Else, looping(foreach while), Loop indexing, etc.

    yes

    Preferably perl

    yes

    Support for data dumper or equivalent plugin from within the template is a plus

    like mentioned above, use escape=dump

    all additional features are listed in the documentation: https://metacpan.org/release/HTML-Template-Compiled at "ADDITIONAL FEATURES"

    edit: regarding reporting runtime errors: unfortunately H::T::C also does not report the template line number for errors that happen at runtime, since it compiles the template to perl-code (I think I experimented with manipulating line numbers once, maybe I'll have another look). template syntax errors are reported with the correct line number.

    edit2: So here's an example with the new options warnings and line_info:

    t/templates/line_info1.html:

    test
    test2
    test3
    foo:<%= foo %> undef line 4
    test4
    

    script:

    use HTML::Template::Compiled;
    my $t = HTML::Template::Compiled->new(
        filename => "t/templates/line_info1.html",
        warnings => 1,
        line_info => 1,
    );
    say $t->output;
    __END__
    Use of uninitialized value in concatenation (.) or string at t/templates/line_info1.html line 4.
    test
    test2
    test3
    foo: undef line 4
    test4
    
    0 讨论(0)
  • 2021-01-30 19:11

    take a look on Template::Semantic for pure template abstraction

    0 讨论(0)
  • 2021-01-30 19:12

    I'm currently experimenting with Template::Alloy and it seems to be, by and large, a drop-in replacement for TT. Template::Alloy::TT lists the differences between TT and Alloy, most of which are of the form "This works/is allowed in Alloy, but not in TT." Addressing your specific issue, the list includes:

    • Alloy has better line information

    When debug dirs is on, directives on different lines separated by colons show the line they are on rather than a general line range.

    Parse errors actually know what line and character they occured at.

    0 讨论(0)
  • 2021-01-30 19:15

    Mojolicious comes with its own templating system Mojo::Template. Its lightweight and can be used even outside of the mojolicious system. Here is an example from the docs:

    use Mojo::Template;
      my $mt = Mojo::Template->new;
    
      # Simple
      my $output = $mt->render(<<'EOF');
      % use Time::Piece;
      <!DOCTYPE html>
      <html>
        <head><title>Simple</title></head>
        % my $now = localtime;
        <body>Time: <%= $now->hms %></body>
      </html>
      EOF
      say $output;
    

    and another

      # More advanced
      my $output = $mt->render(<<'EOF', 23, 'foo bar');
      % my ($number, $text) = @_;
      %= 5 * 5
      <!DOCTYPE html>
      <html>
        <head><title>More advanced</title></head>
        <body>
          test 123
          foo <% my $i = $number + 2; %>
          % for (1 .. 23) {
          * some text <%= $i++ %>
          % }
        </body>
      </html>
      EOF
      say $output;
    
    0 讨论(0)
  • 2021-01-30 19:28

    I can only recommend Text::Xslate here. It is better than TT in every way and beats out most of the competition as well. And lastly, it fits all your requirements. Literally. All of them.

    It is even proven in practice, as it is used by one of the Top 100 websites worldwide and one of the Top 10 websites in Japan: Livedoor

    Xslate in comparison to TT:

    • faster startup
    • faster processing
    • strict mode by default
    • much more advanced strict mode that catches inconsistencies beyond just "var is undef"
    • detailed errors that show the exact template position
    • automatic HTML entity escaping (XSS-safe)
    • actively maintained and not just left to languish
    • syntax is straight-forward and modern perl

    Two things to note for your special case:

    1. As you're porting from TT, you might want to pass syntax => 'TTerse' to the constructor to get a syntax that's designed to be as close to TT as possible.
    2. When generating non-HTML, you want to pass type => 'text' to the constructor to disable html_escape interpolation.
    0 讨论(0)
提交回复
热议问题