File Coverage

blib/lib/Prancer/Plugin/Xslate.pm
Criterion Covered Total %
statement 77 86 89.5
branch 8 32 25.0
condition 4 35 11.4
subroutine 17 21 80.9
pod 5 6 83.3
total 111 180 61.6


line stmt bran cond sub pod time code
1             package Prancer::Plugin::Xslate;
2              
3 2     2   58494 use strict;
  2         10  
  2         98  
4 2     2   12 use warnings FATAL => 'all';
  2         2  
  2         99  
5              
6 2     2   663 use version;
  2         2377  
  2         12  
7             our $VERSION = '1.05';
8              
9 2     2   1234 use Prancer::Plugin;
  2         25737  
  2         75  
10 2     2   15 use parent qw(Prancer::Plugin Exporter);
  2         3  
  2         9  
11              
12 2     2   121 use Prancer::Core;
  2         4  
  2         67  
13 2     2   1290 use Text::Xslate;
  2         20245  
  2         126  
14 2     2   19 use Try::Tiny;
  2         4  
  2         121  
15 2     2   10 use Carp;
  2         3  
  2         360  
16              
17             our @EXPORT_OK = qw(render mark_raw unmark_raw html_escape uri_escape);
18             our %EXPORT_TAGS = ('all' => [ @EXPORT_OK ]);
19              
20             # even though this *should* work automatically, it was not
21             our @CARP_NOT = qw(Prancer Try::Tiny);
22              
23             sub load {
24 9     9 0 165084 my $class = shift;
25              
26             # already got an object
27 9 50       42 return $class if ref($class);
28              
29             # this is a singleton
30 9         19 my $instance = undef;
31             {
32 2     2   20 no strict 'refs';
  2         2  
  2         207  
  9         12  
33 9         15 $instance = \${"${class}::_instance"};
  9         37  
34 9 100       33 return $$instance if defined($$instance);
35             }
36              
37 8         23 my $self = bless({}, $class);
38              
39             # the config is modified and used every time "render" is called
40 8   50     38 $self->{'_config'} = $self->config->get("template") || {};
41              
42             # now export the keyword with a reference to $self
43             {
44             ## no critic (ProhibitNoStrict ProhibitNoWarnings)
45 2     2   10 no strict 'refs';
  2         3  
  2         58  
  8         781  
46 2     2   10 no warnings 'redefine';
  2         9  
  2         1620  
47 8         13 *{"${\__PACKAGE__}::render"} = sub {
  8         128  
48 11 0 33 11   9291 my $this = ref($_[0]) && $_[0]->isa(__PACKAGE__) ?
    50 0        
49             shift : (defined($_[0]) && $_[0] eq __PACKAGE__) ?
50             bless({}, shift) : bless({}, __PACKAGE__);
51 11         36 return $self->_render(@_);
52 8         43 };
53             }
54              
55 8         15 $$instance = $self;
56 8         20 return $self;
57             }
58              
59             sub path {
60 4     4 1 24 my $self = shift;
61 4 50       13 if (@_) {
62 4         41 $self->{'_config'}->{'path'} = shift;
63             }
64 4         13 return $self->{'_config'}->{'path'};
65             }
66              
67             sub _render {
68 11     11   33 my ($self, $template, $vars, $config) = @_;
69              
70             # just pass all of the options directly to Text::Xslate
71             # some default options that are important to remember:
72             # cache = 1
73             # cache_dir = $ENV{'HOME'}/.xslate_cache
74             # verbose = 1
75             # suffix = '.tx'
76             # syntax = 'Kolon'
77             # type = 'html' (identical to xml)
78 11         66 my $tx_config = _merge($self->{'_config'}, $config);
79 11         13 my $tx = Text::Xslate->new(%{$tx_config});
  11         77  
80              
81             # merge configuration values into the template variable list
82 11         8716 my $user_config = $self->config->get();
83 11         404 $vars = _merge({ 'config' => $user_config }, $vars);
84              
85 11         106 return $tx->render($template, $vars);
86             }
87              
88             sub mark_raw {
89 0 0 0 0 1 0 my $self = ref($_[0]) && $_[0]->isa(__PACKAGE__) ?
    0 0        
90             shift : (defined($_[0]) && $_[0] eq __PACKAGE__) ?
91             bless({}, shift) : bless({}, __PACKAGE__);
92 0         0 return Text::Xslate::mark_raw(@_);
93             }
94              
95             sub unmark_raw {
96 0 0 0 0 1 0 my $self = ref($_[0]) && $_[0]->isa(__PACKAGE__) ?
    0 0        
97             shift : (defined($_[0]) && $_[0] eq __PACKAGE__) ?
98             bless({}, shift) : bless({}, __PACKAGE__);
99 0         0 return Text::Xslate::unmark_raw(@_);
100             }
101              
102             sub html_escape {
103 0 0 0 0 1 0 my $self = ref($_[0]) && $_[0]->isa(__PACKAGE__) ?
    0 0        
104             shift : (defined($_[0]) && $_[0] eq __PACKAGE__) ?
105             bless({}, shift) : bless({}, __PACKAGE__);
106 0         0 return Text::Xslate::html_escape(@_);
107             }
108              
109             sub uri_escape {
110 0 0 0 0 1 0 my $self = ref($_[0]) && $_[0]->isa(__PACKAGE__) ?
    0 0        
111             shift : (defined($_[0]) && $_[0] eq __PACKAGE__) ?
112             bless({}, shift) : bless({}, __PACKAGE__);
113 0         0 return Text::Xslate::uri_escape(@_);
114             }
115              
116             # stolen from Hash::Merge::Simple
117             sub _merge {
118 22     22   39 my ($left, @right) = @_;
119              
120 22 50       53 return $left unless @right;
121 22 50       49 return _merge($left, _merge(@right)) if @right > 1;
122              
123 22         28 my ($right) = @right;
124 22         22 my %merged = %{$left};
  22         85  
125              
126 22         28 for my $key (keys %{$right}) {
  22         69  
127 12         18 my ($hr, $hl) = map { ref($_->{$key}) eq "HASH" } $right, $left;
  24         55  
128              
129 12 50 66     43 if ($hr and $hl) {
130 0         0 $merged{$key} = _merge($left->{$key}, $right->{$key});
131             } else {
132 12         33 $merged{$key} = $right->{$key};
133             }
134             }
135              
136 22         52 return \%merged;
137             }
138              
139             1;
140              
141             =head1 NAME
142              
143             Prancer::Plugin::Xslate
144              
145             =head1 SYNOPSIS
146              
147             This plugin provides access to the L templating engine for your
148             L application and exports a keyword to access the configured engine.
149              
150             This template plugin supports setting the basic configuration in your Prancer
151             application's configuration file. You can also configure all options at runtime
152             using arguments to C.
153              
154             To set a configuration in your application's configuration file, begin the
155             configuration block with C