Newer Older
128 lines | 3.566kb
add files
Yuki Kimoto authored on 2014-03-26
1
package Mojolicious::Plugin::EPRenderer;
2
use Mojo::Base 'Mojolicious::Plugin';
3

            
4
use Mojo::Template;
5
use Mojo::Util qw(encode md5_sum monkey_patch);
6

            
7
sub register {
8
  my ($self, $app, $conf) = @_;
9

            
10
  # Auto escape by default to prevent XSS attacks
11
  my $template = {auto_escape => 1, %{$conf->{template} || {}}};
12

            
13
  # Add "ep" handler and make it the default
14
  $app->renderer->default_handler('ep')->add_handler(
15
    $conf->{name} || 'ep' => sub {
16
      my ($renderer, $c, $output, $options) = @_;
17

            
18
      # Generate name
19
      my $path = $options->{inline} || $renderer->template_path($options);
20
      return undef unless defined $path;
21
      my @keys = sort grep {/^\w+$/} keys %{$c->stash};
22
      my $id = encode 'UTF-8', join(',', $path, @keys);
23
      my $key = $options->{cache} = md5_sum $id;
24

            
25
      # Cache template for "epl" handler
26
      my $cache = $renderer->cache;
27
      my $mt    = $cache->get($key);
28
      unless ($mt) {
29
        $mt = Mojo::Template->new($template);
30

            
31
        # Helpers (only once)
32
        ++$self->{helpers} and _helpers($mt->namespace, $renderer->helpers)
33
          unless $self->{helpers};
34

            
35
        # Stash values (every time)
36
        my $prepend = 'my $self = shift; my $_S = $self->stash;';
37
        $prepend .= " my \$$_ = \$_S->{'$_'};" for @keys;
38

            
39
        $cache->set($key => $mt->prepend($prepend . $mt->prepend));
40
      }
41

            
42
      # Make current controller available
43
      no strict 'refs';
44
      no warnings 'redefine';
45
      local *{"@{[$mt->namespace]}::_C"} = sub {$c};
46

            
47
      # Render with "epl" handler
48
      return $renderer->handlers->{epl}->($renderer, $c, $output, $options);
49
    }
50
  );
51
}
52

            
53
sub _helpers {
54
  my ($namespace, $helpers) = @_;
55
  for my $name (grep {/^\w+$/} keys %$helpers) {
56
    monkey_patch $namespace, $name,
57
      sub { $helpers->{$name}->($namespace->_C, @_) };
58
  }
59
}
60

            
61
1;
62

            
63
=encoding utf8
64

            
65
=head1 NAME
66

            
67
Mojolicious::Plugin::EPRenderer - Embedded Perl renderer plugin
68

            
69
=head1 SYNOPSIS
70

            
71
  # Mojolicious
72
  $self->plugin('EPRenderer');
73
  $self->plugin(EPRenderer => {name => 'foo'});
74
  $self->plugin(EPRenderer => {template => {line_start => '.'}});
75

            
76
  # Mojolicious::Lite
77
  plugin 'EPRenderer';
78
  plugin EPRenderer => {name => 'foo'};
79
  plugin EPRenderer => {template => {line_start => '.'}};
80

            
81
=head1 DESCRIPTION
82

            
83
L<Mojolicious::Plugin::EPRenderer> is a renderer for C<ep> templates.
84

            
85
C<ep> or C<Embedded Perl> is a simple template format where you embed perl
86
code into documents. It is based on L<Mojo::Template>, but extends it with
87
some convenient syntax sugar designed specifically for L<Mojolicious>. It
88
supports L<Mojolicious> template helpers and exposes the stash directly as
89
Perl variables.
90

            
91
This is a core plugin, that means it is always enabled and its code a good
92
example for learning to build new plugins, you're welcome to fork it.
93

            
94
=head1 OPTIONS
95

            
96
L<Mojolicious::Plugin::EPRenderer> supports the following options.
97

            
98
=head2 name
99

            
100
  # Mojolicious::Lite
101
  plugin EPRenderer => {name => 'foo'};
102

            
103
Handler name, defaults to C<ep>.
104

            
105
=head2 template
106

            
107
  # Mojolicious::Lite
108
  plugin EPRenderer => {template => {line_start => '.'}};
109

            
110
Attribute values passed to L<Mojo::Template> object used to render templates.
111

            
112
=head1 METHODS
113

            
114
L<Mojolicious::Plugin::EPRenderer> inherits all methods from
115
L<Mojolicious::Plugin> and implements the following new ones.
116

            
117
=head2 register
118

            
119
  $plugin->register(Mojolicious->new);
120
  $plugin->register(Mojolicious->new, {name => 'foo'});
121

            
122
Register renderer in L<Mojolicious> application.
123

            
124
=head1 SEE ALSO
125

            
126
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
127

            
128
=cut