summaryrefslogtreecommitdiffstats
path: root/lib/Plack/Middleware/Xslate.pm
blob: c520931905f45fcee1e19cd80e807a4b3f7b8f88 (plain) (blame)
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
157
158
159
160
161
162
163
package Plack::Middleware::Xslate;
use strict;
use warnings;
# ABSTRACT: serve static templates with Plack

use base 'Plack::Middleware::Static';

use Plack::Util::Accessor 'xslate_args', 'xslate_vars';

use Text::Xslate;

=head1 SYNOPSIS

  use Plack::Builder;

  builder {
      enable "Xslate",
          path => qr{^/}, root => 'root/templates/', pass_through => 1;
      $app;
  };

=head1 DESCRIPTION

This middleware allows you to serve files processed as L<Text::Xslate>
templates. This is useful for serving sites that are essentially static
content, but with a consistent structure (which can be pulled out into a single
template to include, rather than duplicated across every page).

Configuration for this middleware is identical to L<Plack::Middleware::Static>,
with these additional options:

=over 4

=item xslate_args

A hashref of arguments to pass to the L<Text::Xslate> constructor. Note that
you cannot pass a C<path> argument here - it will be overridden by the C<root>
option.

=item xslate_vars

A hashref of data to use when rendering the template. This will be passed to
C<< Text::Xslate->render >> every time a template is rendered.

=back

=cut

sub prepare_app {
    my $self = shift;
    $self->{file} = Plack::App::File::Xslate->new({ root => $self->root || '.', encoding => $self->encoding, xslate_args => $self->xslate_args, xslate_vars => $self->xslate_vars });
    $self->{file}->prepare_app;
}

# XXX copied and pasted from Plack::Middleware::Static just so i can override
# with Plack::App::File::Xslate instead of Plack::App::File - submit a patch
# upstream to make this more configurable
sub _handle_static {
    my($self, $env) = @_;

    my $path_match = $self->path or return;
    my $path = $env->{PATH_INFO};

    for ($path) {
        my $matched = 'CODE' eq ref $path_match ? $path_match->($_) : $_ =~ $path_match;
        return unless $matched;
    }

    local $env->{PATH_INFO} = $path; # rewrite PATH
    return $self->{file}->call($env);
}

package # hide from PAUSE
    Plack::App::File::Xslate;
use strict;
use warnings;

use base 'Plack::App::File';

use Plack::Util::Accessor 'xslate_args', 'xslate_vars';

use File::Spec;
use Cwd 'cwd';

sub prepare_app {
    my $self = shift;

    $self->SUPER::prepare_app(@_);

    $self->content_type('text/html');

    $self->xslate_args({
        %{ $self->xslate_args || {} },
        path => [ $self->root ],
    });
    $self->{xslate} = Text::Xslate->new($self->xslate_args || ());
}

sub serve_path {
    my $self = shift;
    my ($env, $file) = @_;

    my $res = $self->SUPER::serve_path(@_);

    my $filename = $res->[2]->path;
    if (File::Spec->file_name_is_absolute($filename)) {
        $filename = File::Spec->abs2rel($filename, $self->root);
    }

    my $rendered = $self->{xslate}->render($filename, $self->xslate_vars);

    $res->[2] = [ $rendered ];

    return $res;
}

=head1 BUGS

No known bugs.

Please report any bugs through RT: email
C<bug-plack-middleware-xslate at rt.cpan.org>, or browse to
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Plack-Middleware-Xslate>.

=head1 SEE ALSO

L<Plack::Request> - Much of this module's API and implementation were taken
from Plack::Request.

=head1 SUPPORT

You can find this documentation for this module with the perldoc command.

    perldoc Plack::Middleware::Xslate

You can also look for information at:

=over 4

=item * AnnoCPAN: Annotated CPAN documentation

L<http://annocpan.org/dist/Plack-Middleware-Xslate>

=item * CPAN Ratings

L<http://cpanratings.perl.org/d/Plack-Middleware-Xslate>

=item * RT: CPAN's request tracker

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Plack-Middleware-Xslate>

=item * Search CPAN

L<http://search.cpan.org/dist/Plack-Middleware-Xslate>

=back

=for Pod::Coverage
  prepare_app

=cut

1;