This file is indexed.

/usr/share/perl5/Dancer/Template/Abstract.pm is in libdancer-perl 1.3202+dfsg-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
package Dancer::Template::Abstract;
our $AUTHORITY = 'cpan:SUKRIA';
#ABSTRACT: abstract class for Dancer's template engines
$Dancer::Template::Abstract::VERSION = '1.3202';
use strict;
use warnings;
use Carp;

use Dancer::Logger;
use Dancer::Factory::Hook;
use Dancer::FileUtils 'path';
use Dancer::Exception qw(:all);

use base 'Dancer::Engine';

Dancer::Factory::Hook->instance->install_hooks(
    qw/before_template_render after_template_render before_layout_render after_layout_render/
);

# overloads this method to implement the rendering
# args:   $self, $template, $tokens
# return: a string of $template's content processed with $tokens
sub render { confess "render not implemented" }

sub default_tmpl_ext { "tt" }

# Work out the template names to look for; this will be the view name passed
# as-is, and also the view name with the default template extension appended, if
# it did not already end in that.
sub _template_name {
    my ( $self, $view ) = @_;
    my @views = ( $view );
    my $def_tmpl_ext = $self->config->{extension} || $self->default_tmpl_ext();
    push @views, $view .= ".$def_tmpl_ext" if $view !~ /\.\Q$def_tmpl_ext\E$/;
    return @views;
}

sub view {
    my ($self, $view) = @_;

    my $views_dir = Dancer::App->current->setting('views');

    for my $template ($self->_template_name($view)) {
        my $view_path = path($views_dir, $template);
        return $view_path if -f $view_path;
    }

    # No matching view path was found
    return;
}

sub layout {
    my ($self, $layout, $tokens, $content) = @_;

    my $layouts_dir = path(Dancer::App->current->setting('views'), 'layouts');
    my $layout_path;
    for my $layout_name ($self->_template_name($layout)) {
        $layout_path = path($layouts_dir, $layout_name);
        last if -e $layout_path;
    }

    my $full_content;
    if (-e $layout_path) {
        $full_content = Dancer::Template->engine->render(
                                     $layout_path, {%$tokens, content => $content});
    } else {
        $full_content = $content;
        Dancer::Logger::error("Defined layout ($layout) was not found!");
    }
    $full_content;
}

sub apply_renderer {
    my ($self, $view, $tokens) = @_;

    ($tokens, undef) = _prepare_tokens_options($tokens);

    $view = $self->view($view);

    Dancer::Factory::Hook->execute_hooks('before_template_render', $tokens);

    my $content;
    try {
        $content = $self->render($view, $tokens);
    } continuation {
        my ($continuation) = @_;
        # If we have a Route continuation, run the after hook, then
        # propagate the continuation
        Dancer::Factory::Hook->execute_hooks('after_template_render', \$content);
        $continuation->rethrow();
    };

    Dancer::Factory::Hook->execute_hooks('after_template_render', \$content);

    # make sure to avoid ( undef ) in list context return
    defined $content
      and return $content;
    return;
}

sub apply_layout {
    my ($self, $content, $tokens, $options) = @_;

    ($tokens, $options) = _prepare_tokens_options($tokens, $options);

    # If 'layout' was given in the options hashref, use it if it's a true value,
    # or don't use a layout if it was false (0, or undef); if layout wasn't
    # given in the options hashref, go with whatever the current layout setting
    # is.
    my $layout =
      exists $options->{layout}
      ? ($options->{layout} ? $options->{layout} : undef)
      : Dancer::App->current->setting('layout');

    defined $content or return;

    defined $layout or return $content;

    Dancer::Factory::Hook->execute_hooks('before_layout_render', $tokens, \$content);

    my $full_content;

    try {
        $full_content = $self->layout($layout, $tokens, $content);
    } continuation {
        my ($continuation) = @_;
        # If we have a Route continuation, run the after hook, then
        # propagate the continuation
        Dancer::Factory::Hook->execute_hooks('after_layout_render', \$full_content);
        $continuation->rethrow();
    };

    Dancer::Factory::Hook->execute_hooks('after_layout_render', \$full_content);

    # make sure to avoid ( undef ) in list context return
    defined $full_content
      and return $full_content;
    return;
}

sub _prepare_tokens_options {
    my ($tokens, $options) = @_;

    $options ||= {};

    # these are the default tokens provided for template processing
    $tokens ||= {};
    $tokens->{perl_version}   = $];
    $tokens->{dancer_version} = $Dancer::VERSION;
    $tokens->{settings}       = Dancer::Config->settings;

    # If we're processing a request, also add the request object, params and
    # vars as tokens:
    if (my $request = Dancer::SharedData->request) {
        $tokens->{request}        = $request;
        $tokens->{params}         = $request->params;
        $tokens->{vars}           = Dancer::SharedData->vars;
    }

    Dancer::App->current->setting('session')
      and $tokens->{session} = Dancer::Session->get;

    return ($tokens, $options);
}

sub template {
    my ($class, $view, $tokens, $options) = @_;
    my ($content, $full_content);

    my $engine = Dancer::Template->engine;

    # it's important that $tokens is not undef, so that things added to it via
    # a before_template in apply_renderer survive to the apply_layout. GH#354
    $tokens  ||= {};
    $options ||= {};

    if ($view) {
        # check if the requested view exists
        my $view_path = $engine->view($view) || '';
        if ($engine->view_exists($view_path)) {
            $content = $engine->apply_renderer($view, $tokens);
        } else {
            Dancer::Logger::error(
                "Supplied view ($view) not found - $view_path does not exist"
            );
            return Dancer::Error->new(
                          code => 500,
                          message => 'view not found',
                   )->render();
        }
    } else {
        $content = delete $options->{content};
    }

    defined $content and $full_content =
      $engine->apply_layout($content, $tokens, $options);

    defined $full_content
      and return $full_content;

    Dancer::Error->new(
        code    => 404,
        message => "Page not found",
    )->render();
}

sub view_exists { return defined $_[1] &&  -f $_[1] }

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Dancer::Template::Abstract - abstract class for Dancer's template engines

=head1 VERSION

version 1.3202

=head1 DESCRIPTION

This class is provided as a base class for each template engine. Any template
engine must inherit from it and provide a set of methods described below.

=head1 TEMPLATE TOKENS

By default Dancer injects some tokens (or variables) to templates. The
available tokens are:

=over 4

=item C<perl_version>

The current running Perl version.

=item C<dancer_version>

The current running Dancer version.

=item C<settings>

Hash to access current application settings.

=item C<request>

Hash to access your current request.

=item C<params>

Hash to access your request parameters.

=item C<vars>

Hash to access your defined variables (using C<vars>).

=item C<session>

Hash to access your session (if you have session enabled)

=back

=head1 INTERFACE

=over 4

=item B<init()>

The template engine can overload this method if some initialization stuff has to
be done before the template engine is used.

The base class provides a plain init() method that only returns true.

=item B<default_tmpl_ext()>

Template class that inherits this class should override this method to return a default template
extension, example: for Template::Toolkit it returns "tt" and for HTML::Mason it returns "mason".
So when you call C<template 'index';> in your dispatch code, Dancer will look for a file 'index.tt'
or 'index.mason' based on the template you use.

Note 1: when returning the extension string, please do not add a dot in front of the extension
as Dancer will do that.

Note 2: for backwards compatibility abstract class returns "tt" instead of throwing
an exception 'method not implemented'.

User would be able to change the default extension using the
C<<extension>> configuration variable on the template
configuration. For example, for the default (C<Simple>) engine:

     template: "simple"
     engines:
       simple:
         extension: 'tmpl'

=item B<view($view)>

The default behavior of this method is to return the path of the given view,
appending the default template extension (either the value of the C<extension>
setting in the configuration, or the value returned by C<default_tmpl_ext>) if
it is not present in the view name given and no layout template with that exact
name existed.  (In other words, given a layout name C<main>, if C<main> exists
in the layouts dir, it will be used; if not, C<main.tmpl> (where C<tmpl> is the
value of the C<extension> setting, or the value returned by C<default_tmpl_ext>)
will be looked for.)

=item B<view_exists($view_path)>

By default, Dancer::Template::Abstract checks to see if it can find the
view file calling C<view_exists($path_to_file)>. If not, it will
generate a nice error message for the user.

If you are using extending Dancer::Template::Abstract to use a template
system with multiple document roots (like L<Text::XSlate> or
L<Template>), you can override this method to always return true, and
therefore skip this check.

=item B<layout($layout, $tokens, $content)>

The default behavior of this method is to merge a content with a layout.  The
layout file is looked for with similar logic as per C<view> - an exact match
first, then attempting to append the default template extension, if the view
name given did not already end with it.

=item B<render($self, $template, $tokens)>

This method must be implemented by the template engine. Given a template and a
set of tokens, it returns a processed string.

If C<$template> is a reference, it's assumed to be a reference to a string that
contains the template itself. If it's not a reference, it's assumed to be the
path to template file, as a string. The render method will then have to open it
and read its content (Dancer::FileUtils::read_file_content does that job).

This method's return value must be a string which is the result of the
interpolation of C<$tokens> in C<$template>.

If an error occurs, the method should trigger an exception with C<die()>.

Examples :

    # with a template as a file
    $content = $engine->render('/my/template.txt', { var => 42 };

    # with a template as a scalar
    my $template = "here is <% var %>";
    $content = $engine->render(\$template, { var => 42 });

=back

=head1 AUTHOR

This module has been written by Alexis Sukrieh, see L<Dancer> for details.

=head1 AUTHOR

Dancer Core Developers

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2010 by Alexis Sukrieh.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut