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   63003 use strict;
  2         4  
  2         78  
4 2     2   7 use warnings FATAL => 'all';
  2         2  
  2         79  
5              
6 2     2   411 use version;
  2         1491  
  2         10  
7             our $VERSION = '1.04';
8              
9 2     2   992 use Prancer::Plugin;
  2         16095  
  2         52  
10 2     2   11 use parent qw(Prancer::Plugin Exporter);
  2         2  
  2         7  
11              
12 2     2   96 use Prancer::Core;
  2         2  
  2         50  
13 2     2   1034 use Text::Xslate;
  2         17004  
  2         105  
14 2     2   16 use Try::Tiny;
  2         4  
  2         88  
15 2     2   8 use Carp;
  2         2  
  2         228  
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 175568 my $class = shift;
25              
26             # already got an object
27 9 50       36 return $class if ref($class);
28              
29             # this is a singleton
30 9         17 my $instance = undef;
31             {
32 2     2   18 no strict 'refs';
  2         2  
  2         153  
  9         12  
33 9         12 $instance = \${"${class}::_instance"};
  9         38  
34 9 100       27 return $$instance if defined($$instance);
35             }
36              
37 8         19 my $self = bless({}, $class);
38              
39             # the config is modified and used every time "render" is called
40 8   50     32 $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   8 no strict 'refs';
  2         2  
  2         40  
  8         841  
46 2     2   7 no warnings 'redefine';
  2         2  
  2         1398  
47 8         10 *{"${\__PACKAGE__}::render"} = sub {
  8         162  
48 11 0 33 11   9496 my $this = ref($_[0]) && $_[0]->isa(__PACKAGE__) ?
    50 0        
49             shift : (defined($_[0]) && $_[0] eq __PACKAGE__) ?
50             bless({}, shift) : bless({}, __PACKAGE__);
51 11         28 return $self->_render(@_);
52 8         46 };
53             }
54              
55 8         14 $$instance = $self;
56 8         29 return $self;
57             }
58              
59             sub path {
60 4     4 1 23 my $self = shift;
61 4 50       12 if (@_) {
62 4         37 $self->{'_config'}->{'path'} = shift;
63             }
64 4         11 return $self->{'_config'}->{'path'};
65             }
66              
67             sub _render {
68 11     11   39 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         55 my $tx_config = _merge($self->{'_config'}, $config);
79 11         15 my $tx = Text::Xslate->new(%{$tx_config});
  11         76  
80              
81             # merge configuration values into the template variable list
82 11         9309 my $user_config = $self->config->get();
83 11         367 $vars = _merge({ 'config' => $user_config }, $vars);
84              
85 11         93 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   36 my ($left, @right) = @_;
119              
120 22 50       53 return $left unless @right;
121 22 50       50 return _merge($left, _merge(@right)) if @right > 1;
122              
123 22         29 my ($right) = @right;
124 22         22 my %merged = %{$left};
  22         78  
125              
126 22         40 for my $key (keys %{$right}) {
  22         56  
127 12         27 my ($hr, $hl) = map { ref($_->{$key}) eq "HASH" } $right, $left;
  24         50  
128              
129 12 50 66     43 if ($hr and $hl) {
130 0         0 $merged{$key} = _merge($left->{$key}, $right->{$key});
131             } else {
132 12         29 $merged{$key} = $right->{$key};
133             }
134             }
135              
136 22         70 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