The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

EJS::Template - EJS (Embedded JavaScript) template engine

VERSION

Version 0.01

SYNOPSIS

    # Perl
    use EJS::Template;
    EJS::Template->process('source.ejs', {name => 'World'});
    
    # EJS ('source.ejs')
    <% for (var i = 0; i < 3; i++) { %>
    Hello, <%= name %>!
    <% } %>
    
    # Output
    Hello, World!
    Hello, World!
    Hello, World!

Anything inside the <%...%> tag is executed as JavaScript code, and anything inside the <%=...%> tag is replaced by the evaluated value.

Within <%...%>, it is also possible to call print() function:

    # EJS
    <%
      for (var i = 0; i <= 5; i++) {
        if (i % 2 == 1) {
          print("i = ", i, "\n");
        }
      }
    %>
    
    # Output
    i = 1
    i = 3
    i = 5

DESCRIPTION

EJS is a template engine with JavaScript code embedded.

It can be used as a general-purpose template engine to generate text documents, configurations, source code, etc. For web applications, EJS can be used as a template of HTML.

EJS is suitable when template authors should not embed potentially dangerous code such as file system manipulations, command executions, and database connections, while at the same time, they can still utilize JavaScript as a well-established programming language.

METHODS

new

Creates a EJS::Template object with configuration name/value pairs.

Usage:

   my $ejs = EJS::Template->new( [NAME => VALUE, ...] );

process

Usage:

    # Simple
    EJS::Template->process([INPUT [, VARIABLES [, OUTPUT ] ] ]);
    
    # Custom
    my $ejs = EJS::Template->new(...);
    $ejs->process([INPUT [, VARIABLES [, OUTPUT ] ] ]);

INPUT is the EJS source (default: STDIN).

VARIABLES is a hash ref that maps variable names to values bound to JavaScript (default: an empty hash). The values of VARIABLES can be a nested structure of hashes, arrays, strings, numbers, and/or subroutine refs.

OUTPUT is where the final result is written out (default: STDOUT).

See the examples below for possible types of INPUT and OUTPUT.

Examples:

    # Reads the file 'source.ejs' and prints the result to STDOUT
    EJS::Template->process('source.ejs', {name => 'World'});

    # Reads STDIN as the EJS source and writes the result to the file 'output.txt'
    EJS::Template->process(\*STDIN, {name => 'World'}, 'output.txt');

    # Parses the EJS source text and stores the result to the variable $out
    my $out;
    EJS::Template->process(\'Hello <%=name%>', {name => 'World'}, \$out);

apply

Usage:

    EJS::Template->apply(INPUT_TEXT [, VARIABLES]) => OUTPUT_TEXT

Example:

    my $text = EJS::Template->apply('Hello <%= name %>', {name => 'World'});
    print $text;

This method serves as a syntax sugar for the process() method, focused on text-to-text conversion.

parse

Usage:

    EJS::Template->parse([INPUT [, OUTPUT ] ]);

INPUT is the EJS source, and OUTPUT is a JavaScript code, which can then be executed to generate the final output (see execute() method).

The parsed code can be stored in a file as an intermediate code, and can be executed at a later time.

The semantics of INPUT and OUTPUT types are similar to process().

execute

Usage:

    EJS::Template->execute([INPUT [, VARIABLES [, OUTPUT ] ] ]);

INPUT is a JavaScript code generated by parse() method, and OUTPUT is the final result.

The semantics of INPUT and OUTPUT types are similar to process().

DETAILS

Auto-escaping

EJS::Template supports auto-escaping if it is enabled via the new() method.

    EJS::Template->new(escape => 'html')->process(...);

If the escape is set to 'html', all the texts inside <%=...%> are HTML-escaped automatically.

    # Input
    <% var text = "x < y < z"; %>
    <span><%= text %></span>
    
    # Output
    <span>x &lt; y &lt; z</span>

In case a raw HTML needs to be embedded without escaping, it can be annotated like this:

    <%:raw= text %>

In addition, the following escape types are available in a similar manner (both for the escape => config or in each individual tag <%=...%>):

  • html

        <span><%:html= plainText %></span>
  • xml

        <xml><%:xml= plainText %></xml>
  • uri

        <a href="http://example.com?name=<%:uri= value %>">Link</a>
  • quote

        <script type="text/javascript">
          var text = "<%:quote= value %>";
        </script>
  • raw

        <div><%:raw= htmlText %></div>

Trimming white spaces

EJS::Template trims appropriate white spaces around <%...%> (but not around <%=...%>).

It helps the template author generate a fairly well-formatted output:

EJS:

    <ul>
      <% for (var i = 1; i <= 5; i++) { %>
        <li>
          <% if (i % 2 == 1) { %>
            <%=i%> x <%=i%> = <%=i * i%>
          <% } %>
        </li>
      <% } %>
    </ul>

Output:

    <ul>
        <li>
            1 x 1 = 1
        </li>
        <li>
            3 x 3 = 9
        </li>
        <li>
            5 x 5 = 25
        </li>
    </ul>

Note: If no white spaces were trimmed, the result output would look much more ugly, because of extra indent spaces and line breaks around <% for (...) %>, <% if (...) %>, etc.

The trimming occurs only when <% is at the beginning of a line with any indent spaces, and its corresponding %> is at the end of the same or another line with any trailing spaces.

When the above trimming condition is met, any white spaces to the left of <% (not including any line breaks) and any white spaces to the right of %> (including the line break) are trimmed.

Data conversion between Perl and EJS

In the current version, the data conversion is limited to basic types (strings, numbers, hashes, arrays, and functions), although arbitrarily nested structures are allowed.

    EJS::Template::process('sample.ejs', {
        name => 'World',
        hash => {foo => 123, bar => 456, baz => [7, 8, 9]},
        array => ['a'..'z'],
        square => sub {
            my $value = shift;
            return $value * $value;
        }
    });

If a blessed reference in Perl is passed to EJS, it is converted into a basic type.

If a Perl subroutine is invoked from inside EJS, the types of the arguments depend on the JavaScript engine that is in use internally (See "#JavaScript Engines").

    # Perl
    sub printRefs {
        print(ref($_) || '(scalar)', "\n") foreach @_;
    }
    
    EJS::Template->process(\<<END, {printRefs => \&printRefs});
    <%
      printRefs(
        'str',
        123,
        [4, 5, 6],
        {x: 7, y: 8},
        function () {return 90}
      );
    %>
    END
    
    # Output with JavaScript::V8
    (scalar)
    (scalar)
    ARRAY
    HASH
    CODE
    
    # Output with JE
    JE::String
    JE::Number
    JE::Object::Array
    JE::Object
    JE::Object::Function

For portability, it is recommended to keep data types as simple as possible when data is passed between Perl and EJS.

JavaScript Engines

EJS::Template automatically determines the available JavaScript engine from the below:

It is also possible to specify a particular engine:

   EJS::Template->new(engine => 'JE')->process(...);

AUTHOR

Mahiro Ando, <mahiro at cpan.org>

BUGS

Please report any bugs or feature requests to bug-ejs-template at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=EJS-Template. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc EJS::Template

You can also look for information at:

ACKNOWLEDGEMENTS

Many thanks to authors of JavaScript engines for making them available, and to authors of those in the SEE ALSO section for giving me ideas and inspirations.

SEE ALSO

LICENSE AND COPYRIGHT

Copyright 2012 Mahiro Ando.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.