File Coverage

blib/lib/EJS/Template.pm
Criterion Covered Total %
statement 65 71 91.5
branch 17 30 56.6
condition 6 12 50.0
subroutine 16 16 100.0
pod 11 11 100.0
total 115 140 82.1


line stmt bran cond sub pod time code
1 8     8   32138 use 5.006;
  8         19  
2 8     8   26 use strict;
  8         8  
  8         145  
3 8     8   30 use warnings;
  8         19  
  8         262  
4              
5             =head1 NAME
6              
7             EJS::Template - EJS (Embedded JavaScript) template engine
8              
9             =cut
10              
11             package EJS::Template;
12              
13 8     8   2441 use EJS::Template::Executor;
  8         12  
  8         196  
14 8     8   2568 use EJS::Template::Parser;
  8         11  
  8         4587  
15              
16             =head1 VERSION
17              
18             Version 0.07
19              
20             =cut
21              
22             our $VERSION = '0.07';
23              
24             our $context;
25              
26             =head1 SYNOPSIS
27              
28             EJS is an "Embedded JavaScript" template engine.
29              
30             Anything inside the tag C<< <%...%> >> is executed as JavaScript code,
31             and anything inside the tag C<< <%=...%> >> is replaced by the evaluated value.
32              
33             # Perl
34             use EJS::Template;
35             EJS::Template->process('source.ejs', {name => 'World'});
36            
37             # EJS ('source.ejs')
38             <% for (var i = 0; i < 3; i++) { %>
39             Hello, <%= name %>!
40             <% } %>
41            
42             # Output (STDOUT)
43             Hello, World!
44             Hello, World!
45             Hello, World!
46              
47             In the above example, the C method takes an input file path as the
48             first argument and variables passed to JavaScript as the second argument.
49             The output is printed out to STDOUT by default.
50              
51             The C method can optionally take both input and output targets (file
52             paths, IO handles, or scalar refs to strings).
53              
54             EJS::Template->process('source.ejs', {name => 'World'}, 'destination.ejs');
55              
56             A simpler way to apply a template without an external file is to use C
57             method, which looks something like this:
58              
59             my $text = EJS::Template->apply('Hello, <%= name %>!', {name => 'World'});
60              
61             Within C<< <%...%> >>, it is also possible to call C function:
62              
63             # EJS
64             <%
65             for (var i = 0; i < 3; i++) {
66             print("i = ", i, "\n");
67             }
68             %>
69            
70             # Output
71             i = 0
72             i = 1
73             i = 2
74              
75             C supports auto-escaping that minimizes the risk of forgetting
76             HTML-escape every individual variable. (See L for more details.)
77              
78             # Perl
79             my $ejs = EJS::Template->new(escape => 'html'); # Set default escape type
80            
81             $ejs->process('sample.ejs', {
82             address => '"Foo Bar" ', # to be escaped
83             message => '

Hello, World!

', # not to be escaped

84             });
85            
86             # EJS ('<%=' escapes the value, while '<%:raw=' does *not*)
87            

<%= address %>

88            
89             <%:raw= message %>
90            
91            
92             # Output
93            

"Foo Bar" <foo.bar@example.com>

94            
95            

Hello, World!

96            
97              
98             Extra white spaces around C<< <% >> and C<< %> >> are appropriately trimmed
99             so that the result output will look fairly clean intuitively.
100              
101            
102             <% for (...) { %>
103            
  • ...
  • 104             <% } %>
    105            
    106              
    107             In the above example, the C-loop line has the indent whitespace and the line break at the end.
    108             In order to make the result HTML look clean, these whitespaces are automatically removed.
    109             See L for more details.
    110              
    111              
    112             =head1 DESCRIPTION
    113              
    114             EJS is a template with JavaScript code embedded, and this module provides a
    115             template engine to generate output from EJS templates.
    116              
    117             It can be used as a general-purpose template engine to generate text documents,
    118             configurations, source code, etc.
    119             For web applications, EJS can be used as a template of HTML.
    120              
    121             EJS is suitable when template authors should not embed potentially dangerous
    122             code such as file system manipulations, command executions, and database
    123             connections, while at the same time, they can still utilize JavaScript as a
    124             well-established programming language.
    125              
    126             Especially for web applications, there are several different approaches to
    127             implement similar EJS functionality, such as parsing EJS and/or executing
    128             JavaScript on the server side or the browser side.
    129             This module implements both parsing and executing on the server side from that
    130             perspective.
    131              
    132             =head1 METHODS
    133              
    134             =head2 new
    135              
    136             Creates an C object with configuration name/value pairs.
    137              
    138             Usage:
    139              
    140             my $ejs = EJS::Template->new( [NAME => VALUE, ...] );
    141              
    142             Available configurations are as below:
    143              
    144             =over 4
    145              
    146             =item * escape => ESCAPE_TYPE
    147              
    148             Sets the default escape type for all the interpolation tags (C<< <%=...%> >>).
    149              
    150             Possible values are: C<'raw'> (default), C<'html'>, C<'xml'>, C<'uri'>, and
    151             C<'quote'>. See L for more details.
    152              
    153             =item * engine => ENGINE_CLASS
    154              
    155             Sets the JavaScript engine class.
    156             See L for more details.
    157              
    158             =back
    159              
    160             =cut
    161              
    162             sub new {
    163 73     73 1 912 my ($class, %config) = @_;
    164 73         124 my $self = {map {$_ => $config{$_}} qw(engine escape parser executor)};
      292         556  
    165 73         207 return bless $self, $class;
    166             }
    167              
    168             =head2 process
    169              
    170             Usage:
    171              
    172             # Simple
    173             EJS::Template->process([INPUT [, VARIABLES [, OUTPUT ] ] ]);
    174            
    175             # Custom
    176             my $ejs = EJS::Template->new(...);
    177             $ejs->process([INPUT [, VARIABLES [, OUTPUT ] ] ]);
    178              
    179             INPUT is the EJS source (default: STDIN).
    180             It can be either a string (as a file path), a string ref (as a source text), or
    181             an open file handle.
    182              
    183             VARIABLES is a hash ref that maps variable names to values, which are made
    184             available in the JavaScript code (default: an empty hash).
    185             The values of VARIABLES can be a nested structure of hashes, arrays, strings,
    186             numbers, and/or subroutine refs.
    187             A function (subroutine) named C is automatically defined, unless
    188             overwritten in VARIABLES.
    189              
    190             OUTPUT is where the final result is written out (default: STDOUT).
    191             It can be either a string (as a file path), a string ref (as a source text), or
    192             an open file handle.
    193              
    194             Examples:
    195              
    196             # Reads the file 'source.ejs' and prints the result to STDOUT
    197             EJS::Template->process('source.ejs', {name => 'World'});
    198              
    199             # Reads STDIN as the EJS source and writes the result to the file 'output.txt'
    200             EJS::Template->process(\*STDIN, {name => 'World'}, 'output.txt');
    201              
    202             # Parses the EJS source text and stores the result to the variable $out
    203             my $out;
    204             EJS::Template->process(\'Hello <%=name%>', {name => 'World'}, \$out);
    205              
    206             =cut
    207              
    208             sub process {
    209 62     62 1 1314 my ($self, $input, $variables, $output) = @_;
    210 62 100       159 local $context = ref $self ? $self : $self->new();
    211            
    212 62         81 eval {
    213 62         71 my $parsed;
    214 62         159 $context->parse($input, \$parsed);
    215 62         154 $context->execute(\$parsed, $variables, $output);
    216             };
    217            
    218 62 50       143 die $@ if $@;
    219 62         293 return 1;
    220             }
    221              
    222             =head2 apply
    223              
    224             Usage:
    225              
    226             EJS::Template->apply(INPUT_TEXT [, VARIABLES])
    227              
    228             Example:
    229              
    230             my $text = EJS::Template->apply('Hello <%= name %>', {name => 'World'});
    231             print $text;
    232              
    233             This method serves as a syntax sugar for the C method, focused on
    234             text-to-text conversion.
    235              
    236             =cut
    237              
    238             sub apply {
    239 1     1 1 70545 my ($self, $input, $variables) = @_;
    240 1 50       6 local $context = ref $self ? $self : $self->new();
    241 1         1 my $output;
    242            
    243 1         1 eval {
    244 1         3 $context->process(\$input, $variables, \$output);
    245             };
    246            
    247 1 50       2 die $@ if $@;
    248 1         4 return $output;
    249             }
    250              
    251             =head2 parse
    252              
    253             Usage:
    254              
    255             EJS::Template->parse([INPUT [, OUTPUT ] ]);
    256              
    257             INPUT is the EJS source, and OUTPUT is a JavaScript code,
    258             which can then be executed to generate the final output.
    259             (See C method.)
    260              
    261             The parsed code can be stored in a file as an intermediate code,
    262             and can be executed at a later time.
    263              
    264             The semantics of INPUT and OUTPUT types are similar to C.
    265              
    266             =cut
    267              
    268             sub parse {
    269 82     82 1 91 my ($self, $input, $parsed_output) = @_;
    270 82 100       183 local $context = ref $self ? $self : $self->new();
    271            
    272 82         78 eval {
    273 82         184 $context->parser->parse($input, $parsed_output);
    274             };
    275            
    276 82 50       508 die $@ if $@;
    277 82         148 return 1;
    278             }
    279              
    280             =head2 execute
    281              
    282             Usage:
    283              
    284             EJS::Template->execute([INPUT [, VARIABLES [, OUTPUT ] ] ]);
    285              
    286             INPUT is a JavaScript code generated by C method,
    287             and OUTPUT is the final result.
    288              
    289             The semantics of INPUT and OUTPUT types are similar to C.
    290              
    291             =cut
    292              
    293             sub execute {
    294 62     62 1 69 my ($self, $parsed_input, $variables, $output) = @_;
    295 62 50       138 local $context = ref $self ? $self : $self->new();
    296            
    297 62         53 eval {
    298 62         139 $context->executor->execute($parsed_input, $variables, $output);
    299             };
    300            
    301 62 50       151 die $@ if $@;
    302 62         150 return 1;
    303             }
    304              
    305              
    306             =head2 context
    307              
    308             Usage:
    309              
    310             EJS::Template->context;
    311              
    312             Retrieves the C object under the current execution context.
    313              
    314             It is useful when retrieving the object from within the JavaScript execution.
    315              
    316             my $template = EJS::Template->new();
    317              
    318             $template->process(\*STDIN, {
    319             callFromJS => sub {
    320             my $context = EJS::Template->context;
    321             # In this case, $context is the same as $template.
    322             ...
    323             }
    324             });
    325              
    326             The above example is trivial because the current context can also be easily referenced
    327             from the outer C<$template> variable via the closure.
    328             However, even if this subroutine is defined in some other places, the current template
    329             object can always be retrieved via this call.
    330              
    331             =cut
    332              
    333             sub context {
    334 8     8 1 16046 my $class = shift;
    335 8   33     32 $class = ref($class) || $class;
    336 8   33     30 return $context ||= $class->new;
    337             }
    338              
    339             =head2 parser
    340              
    341             Gets or sets an C object.
    342              
    343             # Getter
    344             $template->parser;
    345              
    346             # Setter
    347             $template->parser(EJS::Template::Parser->new($template));
    348              
    349             =cut
    350              
    351             sub parser {
    352 82     82 1 90 my $self = shift;
    353 82 50       168 $self = $self->context unless ref $self;
    354              
    355 82 50       201 if (@_) {
    356 0         0 my $old = $self->{parser};
    357 0         0 $self->{parser} = shift;
    358 0         0 return $old;
    359             } else {
    360 82   66     561 return $self->{parser} ||= EJS::Template::Parser->new($self);
    361             }
    362             }
    363              
    364             =head2 executor
    365              
    366             Gets or sets an C object.
    367              
    368             # Getter
    369             $template->executor;
    370              
    371             # Setter
    372             $template->executor(EJS::Template::Executor->new($template));
    373              
    374             =cut
    375              
    376             sub executor {
    377 73     73 1 79 my $self = shift;
    378 73 50       137 $self = $self->context unless ref $self;
    379              
    380 73 50       157 if (@_) {
    381 0         0 my $old = $self->{executor};
    382 0         0 $self->{executor} = shift;
    383 0         0 return $old;
    384             } else {
    385 73   66     426 return $self->{executor} ||= EJS::Template::Executor->new($self);
    386             }
    387             }
    388              
    389             =head2 bind
    390              
    391             Binds name-value pairs to the associated JavaScript engine.
    392              
    393             $template->bind({name1 => $value1});
    394             $template->apply('<% print("name1 = ", name1) %>');
    395              
    396             =cut
    397              
    398             sub bind {
    399 5     5 1 3884 my $self = shift;
    400 5 50       11 $self = $self->context unless ref $self;
    401 5         10 return $self->executor->adapter->bind(@_);
    402             }
    403              
    404             =head2 eval
    405              
    406             Invokes the C function of the associated JavaScript engine.
    407              
    408             $template->eval('new Date().toString()');
    409              
    410             =cut
    411              
    412             sub eval {
    413 1     1 1 6 my $self = shift;
    414 1 50       3 $self = $self->context unless ref $self;
    415 1         3 return $self->executor->adapter->eval(@_);
    416             }
    417              
    418             =head2 print
    419              
    420             Prints text to the current output target.
    421              
    422             $template->print('Hello, World!');
    423              
    424             This method can only be called under the execution context, usually from
    425             within a subroutine invoked by JavaScript.
    426              
    427             $template->process('example.ejs', {
    428             callFromJS => sub {
    429             $template->print('Hello, World!');
    430             }
    431             });
    432              
    433             =cut
    434              
    435             sub print {
    436 5     5 1 3230 my $self = shift;
    437 5 50       11 $self = $self->context unless ref $self;
    438 5         10 return $self->executor->print(@_);
    439             }
    440              
    441              
    442             =head1 DETAILS
    443              
    444             =head2 Auto-escaping
    445              
    446             C supports auto-escaping if it is configured via the C
    447             method.
    448              
    449             EJS::Template->new(escape => 'html')->process(...);
    450              
    451             If the C is set to 'html', all the texts inside C<< <%=...%> >> are
    452             HTML-escaped automatically.
    453              
    454             # Input
    455             <% var text = "x < y < z"; %>
    456             <%= text %>
    457            
    458             # Output
    459             x < y < z
    460              
    461             In case a raw HTML needs to be embedded without escaping, it can be annotated like this:
    462              
    463             <%:raw= text %>
    464              
    465             In addition, the following escape types are available in a similar manner
    466             (both for the C<< escape => >> config or in each individual tag C<< <%=...%> >>):
    467              
    468             =over 4
    469              
    470             =item * html
    471              
    472             <%:html= plainText %>
    473              
    474             =item * xml
    475              
    476             <%:xml= plainText %>
    477              
    478             =item * uri
    479              
    480             Link
    481              
    482             =item * quote
    483              
    484            
    487              
    488             =item * raw
    489              
    490            
    <%:raw= htmlText %>
    491              
    492             =back
    493              
    494             =head2 Trimming white spaces
    495              
    496             C trims appropriate white spaces around C<< <%...%> >>
    497             (but not around C<< <%=...%> >>).
    498              
    499             It helps the template author generate a fairly well-formatted output:
    500              
    501             EJS:
    502              
    503            
    504             <% for (var i = 1; i <= 5; i++) { %>
    505            
  • 506             <% if (i % 2 == 1) { %>
    507             <%=i%> x <%=i%> = <%=i * i%>
    508             <% } %>
    509            
    510             <% } %>
    511            
    512              
    513             Output:
    514              
    515            
    516            
  • 517             1 x 1 = 1
    518            
    519            
  • 520             3 x 3 = 9
    521            
    522            
  • 523             5 x 5 = 25
    524            
    525            
    526              
    527             Note: If no white spaces were trimmed, the result output would look much more ugly,
    528             because of extra indent spaces and line breaks around C<< <% for (...) %> >>,
    529             C<< <% if (...) %> >>, etc.
    530              
    531             The trimming occurs only when C<< <% >> is at the beginning of a line with any indent
    532             spaces, and its corresponding C<< %> >> is at the end of the same or another line
    533             with any trailing spaces.
    534              
    535             When the above trimming condition is met,
    536             any white spaces to the left of C<< <% >> (not including any line breaks) and
    537             any white spaces to the right of C<< %> >> (including the line break) are trimmed.
    538              
    539             =head2 Data conversion between Perl and EJS
    540              
    541             In the current version, the data conversion is limited to basic types
    542             (strings, numbers, hashes, arrays, and functions), although arbitrarily nested
    543             structures are allowed.
    544              
    545             EJS::Template->process('sample.ejs', {
    546             name => 'World',
    547             hash => {foo => 123, bar => 456, baz => [7, 8, 9]},
    548             array => ['a'..'z'],
    549             square => sub {
    550             my $value = shift;
    551             return $value * $value;
    552             }
    553             });
    554              
    555             If a blessed reference in Perl is passed to EJS, it is converted into a basic type.
    556              
    557             If a Perl subroutine is invoked from inside EJS, the types of the arguments depend
    558             on the JavaScript engine that is in use internally (See L).
    559              
    560             # Perl
    561             sub printRefs {
    562             print(ref($_) || '(scalar)', "\n") foreach @_;
    563             }
    564            
    565             EJS::Template->process(\< \&printRefs});
    566             <%
    567             printRefs(
    568             'str',
    569             123,
    570             [4, 5, 6],
    571             {x: 7, y: 8},
    572             function () {return 90}
    573             );
    574             %>
    575             END
    576            
    577             # Output with JavaScript::V8
    578             (scalar)
    579             (scalar)
    580             ARRAY
    581             HASH
    582             CODE
    583            
    584             # Output with JE
    585             JE::String
    586             JE::Number
    587             JE::Object::Array
    588             JE::Object
    589             JE::Object::Function
    590              
    591             For portability, it is recommended to keep data types as simple as possible
    592             when data is passed between Perl and EJS.
    593              
    594             =head2 JavaScript engines
    595              
    596             C automatically determines the available JavaScript engine from
    597             the below:
    598              
    599             =over 4
    600              
    601             =item * V8 (same engine as Google Chrome):
    602              
    603             L (default for C)
    604              
    605             =item * SpiderMonkey (same engine as Mozilla Firefox):
    606              
    607             L
    608              
    609             L
    610              
    611             =item * Pure Perl implementation
    612              
    613             L
    614              
    615             =back
    616              
    617             It is also possible to specify a particular engine:
    618              
    619             EJS::Template->new(engine => 'JE')->process(...);
    620             EJS::Template->new(engine => 'JavaScript::SpiderMonkey')->process(...);
    621              
    622             =head2 Including another EJS file
    623              
    624             Although this module does not provide the C function as a built-in,
    625             it can be implemented as below, depending on the use case.
    626              
    627             # Perl
    628             my $template = EJS::Template->new({escape => 'html'});
    629             $template->process('index.html.ejs', {
    630             include => sub {
    631             my ($path) = @_;
    632             # TODO: Validate $path to avoid reading arbitrary files
    633             my $context = EJS::Template->context;
    634             $context->process($path);
    635             }
    636             });
    637              
    638             # EJS (index.html.ejs)
    639             <%
    640             include('header.html.ejs');
    641             include('content.html.ejs');
    642             include('footer.html.ejs');
    643             %>
    644              
    645             =head1 AUTHOR
    646              
    647             Mahiro Ando, C<< >>
    648              
    649             =head1 BUGS
    650              
    651             Please report any bugs or feature requests to C, or through
    652             the web interface at L. I will be notified, and then you'll
    653             automatically be notified of progress on your bug as I make changes.
    654              
    655             =head1 SUPPORT
    656              
    657             You can find documentation for this module with the perldoc command.
    658              
    659             perldoc EJS::Template
    660              
    661             You can also look for information at:
    662              
    663             =over 4
    664              
    665             =item * GitHub repository (report bugs here)
    666              
    667             L
    668              
    669             =item * RT: CPAN's request tracker (report bugs here, alternatively)
    670              
    671             L
    672              
    673             =item * AnnoCPAN: Annotated CPAN documentation
    674              
    675             L
    676              
    677             =item * CPAN Ratings
    678              
    679             L
    680              
    681             =item * Search CPAN
    682              
    683             L
    684              
    685             =back
    686              
    687             =head1 ACKNOWLEDGEMENTS
    688              
    689             Many thanks to authors of JavaScript engines for making them available,
    690             and to authors of those in the SEE ALSO section for giving me
    691             ideas and inspirations.
    692              
    693             =head1 SEE ALSO
    694              
    695             =over 4
    696              
    697             =item * Template Toolkit (a.k.a. TT)
    698              
    699             L
    700              
    701             =item * JavaScript Template engine based on TT2
    702              
    703             L
    704              
    705             =item * Browser-side EJS
    706              
    707             L
    708              
    709             L
    710              
    711             =item * EJS for Ruby:
    712              
    713             L
    714              
    715             =back
    716              
    717             =head1 LICENSE AND COPYRIGHT
    718              
    719             Copyright 2012 Mahiro Ando.
    720              
    721             This program is free software; you can redistribute it and/or modify it
    722             under the terms of either: the GNU General Public License as published
    723             by the Free Software Foundation; or the Artistic License.
    724              
    725             See http://dev.perl.org/licenses/ for more information.
    726              
    727             =cut
    728              
    729             1; # End of EJS::Template