Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/andinus/templatenestfast
Template::Nest::Fast is a high-performance template engine module for Raku
https://github.com/andinus/templatenestfast
raku template-engine
Last synced: about 1 month ago
JSON representation
Template::Nest::Fast is a high-performance template engine module for Raku
- Host: GitHub
- URL: https://github.com/andinus/templatenestfast
- Owner: andinus
- License: isc
- Created: 2023-03-28T04:45:31.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-11-18T16:52:36.000Z (2 months ago)
- Last Synced: 2024-11-18T18:02:11.321Z (2 months ago)
- Topics: raku, template-engine
- Language: Raku
- Homepage: https://raku.land/zef:andinus/Template::Nest::Fast
- Size: 166 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.org
- License: LICENSE
Awesome Lists containing this project
README
#+title: Template::Nest::Fast
#+subtitle: manipulate a generic template structure via a Raku hash* Documentation
~Template::Nest::Fast~ is a high-performance template engine module for Raku,
designed to process nested templates quickly and efficiently. This module
improves on the original ~Template::Nest~ module by caching the index of
positions of variables, resulting in significantly faster processing times.For more details on ~Template::Nest~ visit:
https://metacpan.org/pod/Template::NestNote: This module was created by me as a proof-of-concept to benchmark against
~Template::Nest::XS~. Tom Gracey (virtual.blue) is currently sponsoring for the
development of this module. He authored ~Template::Nest~ originally in Perl 5.Note: ~Template::Nest::XS~ is the recommended module for use in production.
Considerable effort has gone into optimising ~Template::Nest::XS~, and it is now
blindingly fast. Make sure to use the latest version (v0.1.9 at the time of
writing), as some instabilities have recently been resolved.As a pure Raku version, you may also find this module (Template::Nest::Fast)
useful for development/testing purposes - as e.g. a full stack trace can be
obtained from it (unlike the XS version which is more of a black box). There may
be other circumstances where this module is useful. However be aware it is
approx 25 times slower than the XS version.It is not recommended to use the original pure Raku version of ~Template::Nest~.
This module was a line by line rewrite of the Perl 5 module - which
unfortunately turned out to be far too slow to be practical.** Options
- Note: The options have their hypen counterparts. For example, ~comment_delims~
is now ~comment-delims~. However, for compatibility with other ::Nest
versions, underscored options are supported on object creation.Compatibility Progress:
#+begin_src
[X] comment_delims
[X] defaults
[X] defaults_namespace_char
[X] die_on_bad_params
[ ] escape_char - Won't be implemented
[X] fixed_indent
[X] name_label
[X] show_labels
[X] template_dir
[X] template_ext
[X] token_delims
#+end_src- Note: ~escape_char~ has been replaced with ~token-escape-char~.
- Note: ~cache-template~ option has been added and is enabled by default.- ~name-label~ (default ~TEMPLATE~): Represents the label used for
identifying the template name in the hash of template variables.- ~template-dir~: IO object representing the directory where the
templates are located.- ~cache-template~ (default: ~True~): If True then the whole template
file is cached in memory, this improves performance.- ~die-on-bad-params~ (default: ~False~): If True, then an attempt to
populate a template with a variable that doesn't exist (i.e. name
not found in template file) results in an error.Note that it allows to leave variables undefined (i.e. name found in
template file but not defined in template hash). Undefined variables
are replaced with empty string. This is for compatibility with
Template::Nest (Raku).You might want to keep this enabled during development & testing.
- ~show-labels~ (default: ~False~): If True, an string is appended to
every rendered template which is helpful in identifying which
template the output text came from. This is useful in development
when you have many templates.Example:
#+begin_src html
Simple Page
A fairly simple page to test the performance of Template::Nest.
Simple Variable
Simple Variable in Simple Component
#+end_src
Here, 'BEGIN' & 'END' blocks have been added because ~show-labels~
was set to True.If you're not templating HTML and still want labels, you can set
~comment-delims~.- ~comment-delims~ (default: ~['']~): Use this in
conjunction with ~show-labels~. Expects a 2 element array. Example,
for templating JS you could do:#+begin_src raku
my $nest-alt = Template::Nest::Fast.new(
:$template-dir, :show-labels, comment-delims => ['/*', '*/']
);
#+end_srcExample output:
#+begin_src js
/* BEGIN js-file */
...
/* END js-file */
#+end_srcYou can set the second comment token as an empty string if the
language you are templating does not use one. Example, for
templating Raku you could do:#+begin_src raku
my $nest-alt = Template::Nest::Fast.new(
:$template-dir, :show-labels, comment-delims => ['#', '']
);
#+end_srcExample output:
#+begin_src raku
# BEGIN raku-file
...
# END raku-file */
#+end_src- ~template-extension~ (default: ~html~): get/set the template
extension. This is so you can save typing your template extension
all the time if it's always the same. There is no reason why this
templating system could not be used to construct any other type of
file (or why you could not use another extension even if you were
producing html). Example, to manipulate JavaScript files, this will
look for ~30-main.js~ in ~$template-dir~:#+begin_src raku
my $nest-js = Template::Nest::Fast.new: :$template-dir, :template-extension('js');
my %simple-page-js = %(
TEMPLATE => '30-main',
var => 'Simple Variable',
);
#+end_srcOr if you have an empty ~template-extension~, this will look for
~30-main.html~ in ~$template-dir~:
#+begin_src raku
my $nest = Template::Nest::Fast.new: :$template-dir, :template-extension('');
my %simple-page-js = %(
TEMPLATE => '30-main.html',
var => 'Simple Variable',
);
#+end_src- ~fixed-indent~ (default: ~False~): Intended to improve readability
when inspecting nested templates. For example, consider these templates:wrapper.html:
#+begin_src html
#+end_srcphoto.html:
#+begin_src html
#+end_srcOutput without ~fixed-indent~:
#+begin_src html
#+end_srcOutput with ~fixed-indent~:
#+begin_src html
#+end_src- ~token-delims~ (default: ~['']~): Set the delimiters
that define a token (to be replaced). For example, setting
~token-delims~ to ~['<%', '%>']~ would mean that ~render~ will now
recognize and interpolate tokens in the format:#+begin_src
<% variable %>
#+end_src- ~token-escape-char~ (default: empty string): On rare occasions you
may actually want to use the exact character string you are using
for your token delimiters in one of your templates. For example,
here ~render~ is going to consider this as a token and remove it:#+begin_src
did you know we are using token delimiters in our templates?
#+end_srcTo include the token, escape it with ~token-escape-char~ set to
(~\~):
#+begin_src
did you know we are using token delimiters \ in our templates?
#+end_srcSet it to an empty string to disable the behaviour.
- ~defaults~: Provide a hash of default values that are substituted if
template hash does not provide a value. For example, passing this
defaults hash:#+begin_src raku
my $nest = Template::Nest::Fast.new(
:$template-dir,
defaults => %(
variable => 'Simple Variable',
space => %(
inside => 'A variable inside a space.'
)
),
);
#+end_srcThis ~$nest~ will first look for variable in template hash, then in
~%defaults~ hash. If no value is found then namespaced defaults are
considered (look ~defaults-namespace-char~).- ~defaults-namespace-char~ (default: ~.~): Say you want to namespace
values in ~%defaults~ hash to differentiate parameters coming from
template hash and chose to prefix those variables like so:#+begin_src html
-
#+end_srcYou can pass a defaults like:
#+begin_src raku
%(
"config.title" => "Title",
"config.description" => "Description"
)
#+end_srcHowever, writing ~config.~ repeatedly is a bit effortful, so you can
do the following:
#+begin_src raku
%(
config => %(
"title" => "Title",
"description" => "Description"
)
)
#+end_srcNote: To disable this behaviour set ~defaults-namespace-char~ to an
empty string.- ~advanced-indexing~ (default: False): When enabled, ~::Fast~ stores the
timestamp of template file index and if the file on disk is newer, it
re-indexes the file. It also indexes files that are present on disk but
weren't indexed when ~::Fast~ was initialized.** Methods
- ~render~: Converts a template structure to output text. See Example
for details.** Example
Templates:
~templates/00-simple-page.html~:
#+begin_src html
Simple Page
A fairly simple page to test the performance of Template::Nest.
#+end_src
~templates/01-simple-component.html~:
#+begin_src html
#+end_src*** Simple template hash
This is a simple example that injects a variable in a template. We use
another template as a component as well.#+begin_src raku
use Template::Nest::Fast;# Create a nest object.
my $nest = Template::Nest::Fast.new( template-dir => 'templates/'.IO );# Declare template structure.
my %simple-page = %(
TEMPLATE => '00-simple-page',
variable => 'Simple Variable',
simple_component => %(
TEMPLATE => '01-simple-component',
variable => 'Simple Variable in Simple Component'
)
);# Render the page.
put $nest.render(%simple-page);
#+end_srcOutput:
#+begin_src html
Simple Page
A fairly simple page to test the performance of Template::Nest.
Simple Variable
Simple Variable in Simple Component
#+end_src
*** Array of template hash
Array of template hash can be passed to ~render~ too.
#+begin_src raku
$nest.render(
[
%( TEMPLATE => '01-simple-component', variable => 'This is a variable' ),
%( TEMPLATE => '01-simple-component', variable => 'This is another variable' )
]
)
#+end_srcOutput:
#+begin_src htmlThis is a variable
This is another variable
#+end_src*** Array to template variable
Template variable can be a string, another template hash or an array too. The
array itself can contain template hash, string or nested array.#+begin_src raku
my %simple-page-arrays = %(
TEMPLATE => '00-simple-page',
variable => 'Simple Variable',
simple_component => [
# Hash passed.
%(
TEMPLATE => '01-simple-component',
variable => 'Simple Variable in Simple Component'
),
# Can pass string as well.
"Another test",
# Or another level of nesting.
[
%(
TEMPLATE => '01-simple-component',
variable => 'Simple Variable in Simple Component'
),
"Another nested test 2"
]
]
);
#+end_srcOutput:
#+begin_src html
Simple Page
A fairly simple page to test the performance of Template::Nest.
Simple Variable
Simple Variable in Simple Component
Another testSimple Variable in Simple Component
Another nested test 2
#+end_src
* News
** v0.3.0 - 2024-11-18
+ Bug Fix: Handle an escaped variable at beginning of a file. Earlier the
program didn't treat it like an escaped variable.** v0.2.8 - 2023-06-27
+ Bug Fix: Earlier Seq was rendered as Str, now it is considered a List.
** v0.2.6 - 2023-05-29
+ Improve error message for die-on-bad-params.
+ Add more tests for advanced-indexing & die-on-bad-params.
+ Handle template file vanishing errors.
Handles errors where the template file has vanished.
+ Fixed a bug where ::Fast does not die on non-existent template file.
This was introduced in v0.2.5 with advanced indexing option.
** v0.2.5 - 2023-05-25
+ Add advanced indexing option.
When enabled, ~::Fast~ stores the timestamp of template file index and if the
file on disk is newer, it re-indexes the file. It also indexes files that are
present on disk but weren't indexed when ~::Fast~ was initialized.** v0.2.4 - 2023-05-22
+ Add support for passing array to render method.
Template::Nest [Perl5] supports this.
Basic Example:
#+begin_src raku
$nest.render(
[
%( TEMPLATE => '01-simple-component', variable => 'This is a variable' ),
%( TEMPLATE => '01-simple-component', variable => 'This is another variable' )
]
)
#+end_srcOutput:
#+begin_src htmlThis is a variable
This is another variable
#+end_src+ Add examples for passing array to render method and passing array to a
template variable.** v0.2.3 - 2023-05-14
+ Add support for underscored options.
This makes the module close to drop-in for projects that use other Nest
versions with support for underscored options.+ Add support for Str, nested List when parsing hash template values.
While parsing hash template values, when we encounter a list we assume
that all the elements will be Hash. This breaks that assumption and
allows for the elements to be of type Hash, Str or even List.After this change, template hash like this will be supported:
#+begin_src raku
my %simple-page-arrays = %(
TEMPLATE => '00-simple-page',
variable => 'Simple Variable',
simple_component => [
# Hash passed.
%(
TEMPLATE => '01-simple-component',
variable => 'Simple Variable in Simple Component'
),
# Can pass string as well.
"Another test",
# Or another level of nesting.
[
%(
TEMPLATE => '01-simple-component',
variable => 'Simple Variable in Simple Component'
),
"Another nested test 2"
]
]
);
#+end_src** v0.2.2 - 2023-05-07
+ Fixed failing tests.
** v0.2.1 - 2023-05-04
+ Fixed parsing bug with non-string values in template hash
Template hash with non-string values like:
#+begin_src raku
my %template = %(
TEMPLATE => 'simple-template',
count => 200 # will result in failure
);
#+end_srcfailed to parse prior to v0.2.1, this has been fixed in v0.2.1.
+ Improve error message for invalid template hash.
** v0.2.0 - 2023-05-02
+ Achieved options compatibility with Template::Nest (Raku).
+ Added several options:
- ~cache-template~
- ~die-on-bad-params~
- ~show-labels~
- ~comment-delims~
- ~template-extension~
- ~fixed-indent~
- ~token-delims~
- ~token-escape-char~
- ~defaults~
- ~defaults-namespace-char~+ Note: It's not backwards compatible with Template::Nest (Raku).
** v0.1.0 - 2023-03-28
+ Initial Release.
* See Also
- Template::Nest [Perl5] https://metacpan.org/pod/Template::Nest
- template-nest [Python] https://pypi.org/project/template-nest/
- Template::Nest [Raku] https://raku.land/cpan:TOMGRACEY/Template::Nest
- Template::Nest::XS [Raku] https://raku.land/zef:jaffa4/Template::Nest::XS