| Dancer documentation | Contained in the Dancer distribution. |
Dancer::Template::Simple - pure Perl 5 template engine for Dancer
This template engine is provided as a default one for the Dancer micro framework.
This template engine should be fine for development purposes but is not a powerful one, it's written in pure Perl and has no C bindings to accelerate the template processing.
If you want to power an application with Dancer in production environment, it's strongly advised to switch to Dancer::Template::TemplateToolkit.
A template written for Dancer::Template::Simple should be working just fine with Dancer::Template::TemplateToolkit. The opposite is not true though.
To interpolate a variable in the template, use the following syntax:
<% var1 %>
If 'var1' exists in the tokens hash given, its value will be written there.
This module has been written by Alexis Sukrieh.
This module is free software and is released under the same terms as Perl itself.
| Dancer documentation | Contained in the Dancer distribution. |
package Dancer::Template::Simple; use strict; use warnings; use Carp; use base 'Dancer::Template::Abstract'; Dancer::Template::Simple->attributes('start_tag', 'stop_tag'); use Dancer::FileUtils 'read_file_content'; sub init { my $self = shift; my $settings = $self->config; my $start = $settings->{'start_tag'} || '<%'; my $stop = $settings->{'stop_tag'} || '%>'; $self->start_tag($start) unless defined $self->start_tag; $self->stop_tag($stop) unless defined $self->stop_tag; } sub render { my ($self, $template, $tokens) = @_; my $content; $content = _read_content_from_template($template); $content = $self->parse_branches($content, $tokens); return $content; } sub parse_branches { my ($self, $content, $tokens) = @_; my ($start, $stop) = ($self->start_tag, $self->stop_tag); my @buffer; my $prefix = ""; my $should_bufferize = 1; my $bufferize_if_token = 0; # $content =~ s/\Q${start}\E(\S)/${start} $1/sg; # $content =~ s/(\S)\Q${stop}\E/$1 ${stop}/sg; # we get here a list of tokens without the start/stop tags my @full = split(/\Q$start\E\s*(.*?)\s*\Q$stop\E/, $content); # and here a list of tokens without variables my @flat = split(/\Q$start\E\s*.*?\s*\Q$stop\E/, $content); # eg: for 'foo=<% var %>' # @full = ('foo=', 'var') # @flat = ('foo=') my $flat_index = 0; my $full_index = 0; for my $word (@full) { # flat word, nothing to do if (defined $flat[$flat_index] && ($flat[$flat_index] eq $full[$full_index])) { push @buffer, $word if $should_bufferize; $flat_index++; $full_index++; next; } my @to_parse = ($word); @to_parse = split(/\s+/, $word) if $word =~ /\s+/; for my $w (@to_parse) { if ($w eq 'if') { $bufferize_if_token = 1; } elsif ($w eq 'else') { $should_bufferize = !$should_bufferize; } elsif ($w eq 'end') { $should_bufferize = 1; } elsif ($bufferize_if_token) { my $bool = _find_value_from_token_name($w, $tokens); $should_bufferize = _interpolate_value($bool) ? 1 : 0; $bufferize_if_token = 0; } elsif ($should_bufferize) { my $val = _interpolate_value(_find_value_from_token_name($w, $tokens)); push @buffer, $val; } } $full_index++; } return join "", @buffer; } # private sub _read_content_from_template { my ($template) = @_; my $content = undef; if (ref($template)) { $content = $$template; } else { croak "'$template' is not a regular file" unless -f $template; $content = read_file_content($template); croak "unable to read content for file $template" if not defined $content; } return $content; } sub _find_value_from_token_name { my ($key, $tokens) = @_; my $value = undef; my @elements = split /\./, $key; foreach my $e (@elements) { if (not defined $value) { $value = $tokens->{$e}; } elsif (ref($value) eq 'HASH') { $value = $value->{$e}; } elsif (ref($value)) { local $@; eval { $value = $value->$e }; $value = "" if $@; } } return $value; } sub _interpolate_value { my ($value) = @_; if (ref($value) eq 'CODE') { local $@; eval { $value = $value->() }; $value = "" if $@; } elsif (ref($value) eq 'ARRAY') { $value = "@{$value}"; } $value = "" if not defined $value; return $value; } 1; __END__