1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
# Copyright (C) 2008-2010, Sebastian Riedel.
package Mojolicious::Plugin::EpRenderer;
use strict;
use warnings;
use base 'Mojolicious::Plugin';
use Mojo::ByteStream 'b';
use Mojo::Template;
# What do you want?
# I'm here to kick your ass!
# Wishful thinking. We have long since evolved beyond the need for asses.
sub register {
my ($self, $app, $conf) = @_;
# Config
$conf ||= {};
my $name = $conf->{name} || 'ep';
my $template = $conf->{template} || {};
# Auto escape by default to prevent XSS attacks
$template->{auto_escape} = 1 unless defined $template->{auto_escape};
# Add "ep" handler
$app->renderer->add_handler(
$name => sub {
my ($r, $c, $output, $options) = @_;
# Generate name
return unless my $path = $r->template_path($options);
my $list = join ', ', sort keys %{$c->stash};
my $cache = $options->{cache} =
b("$path($list)")->md5_sum->to_string;
# Stash defaults
$c->stash->{layout} ||= undef;
# Reload
delete $r->{_epl_cache} if $ENV{MOJO_RELOAD};
local $ENV{MOJO_RELOAD} = 0 if $ENV{MOJO_RELOAD};
# Cache
$r->{_epl_cache} ||= {};
unless ($r->{_epl_cache}->{$cache}) {
# Debug
$c->app->log->debug(
qq/Caching template "$path" with stash "$list"./);
# Initialize
$template->{namespace} ||= "Mojo::Template::$cache";
my $mt = $r->{_epl_cache}->{$cache} =
Mojo::Template->new($template);
# Self
my $prepend = 'my $self = shift;';
# Weaken
$prepend .= q/use Scalar::Util 'weaken'; weaken $self;/;
# Be a bit more relaxed for helpers
$prepend .= q/no strict 'refs'; no warnings 'redefine';/;
# Helpers
$prepend .= 'my $_H = $self->app->renderer->helper;';
for my $name (sort keys %{$r->helper}) {
next unless $name =~ /^\w+$/;
$prepend .= "sub $name; *$name = sub { ";
$prepend .= "return \$_H->{'$name'}->(\$self, \@_) };";
}
# Be less relaxed for everything else
$prepend .= q/use strict; use warnings;/;
# Stash
for my $var (keys %{$c->stash}) {
next unless $var =~ /^\w+$/;
$prepend .= " my \$$var = \$self->stash->{'$var'};";
}
# Prepend
$mt->prepend($prepend);
}
# Render with epl
return $r->handler->{epl}->($r, $c, $output, $options);
}
);
# Set default handler
$app->renderer->default_handler('ep');
}
1;
__END__
=head1 NAME
Mojolicious::Plugin::EpRenderer - EP Renderer Plugin
=head1 SYNOPSIS
# Mojolicious
$self->plugin('ep_renderer');
$self->plugin(ep_renderer => {name => 'foo'});
$self->plugin(ep_renderer => {template => {line_start => '.'}});
# Mojolicious::Lite
plugin 'ep_renderer';
plugin ep_renderer => {name => 'foo'};
plugin ep_renderer => {template => {line_start => '.'}};
=head1 DESCRIPTION
L<Mojolicous::Plugin::EpRenderer> is a renderer for C<ep> templates.
=head1 TEMPLATES
C<ep> or C<Embedded Perl> is a simple template format where you embed perl
code into documents.
It is based on L<Mojo::Template>, but extends it with some convenient syntax
sugar designed specifically for L<Mojolicious>.
It supports L<Mojolicious> template helpers and exposes the stash directly as
perl variables.
=head1 OPTIONS
=head2 C<name>
# Mojolicious::Lite
plugin ep_renderer => {name => 'foo'};
=head2 C<template>
# Mojolicious::Lite
plugin ep_renderer => {template => {line_start => '.'}};
=head1 METHODS
L<Mojolicious::Plugin::EpRenderer> inherits all methods from
L<Mojolicious::Plugin> and implements the following new ones.
=head2 C<register>
$plugin->register;
Register renderer in L<Mojolicious> application.
=head1 SEE ALSO
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicious.org>.
=cut
|