File Coverage

blib/lib/EJS/Template.pm
Criterion Covered Total %
statement 62 71 87.3
branch 16 30 53.3
condition 6 12 50.0
subroutine 15 16 93.7
pod 11 11 100.0
total 110 140 78.5


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

Hello, World!

', # not to be escaped

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

<%= address %>

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

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

95            
96            

Hello, World!

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