template: Preprocess parameters before htmlizing.
[ikiwiki] / IkiWiki / Plugin / template.pm
1 #!/usr/bin/perl
2 # Structured template plugin.
3 package IkiWiki::Plugin::template;
4
5 use warnings;
6 use strict;
7 use IkiWiki 3.00;
8 use HTML::Template;
9 use Encode;
10
11 sub import {
12         hook(type => "getsetup", id => "template", call => \&getsetup);
13         hook(type => "preprocess", id => "template", call => \&preprocess,
14                 scan => 1);
15 }
16
17 sub getsetup () {
18         return
19                 plugin => {
20                         safe => 1,
21                         rebuild => undef,
22                 },
23 }
24
25 sub preprocess (@) {
26         my %params=@_;
27
28         # This needs to run even in scan mode, in order to process
29         # links and other metadata included via the template.
30         my $scan=! defined wantarray;
31
32         if (! exists $params{id}) {
33                 error gettext("missing id parameter")
34         }
35
36         my $template_page="templates/$params{id}";
37         add_depends($params{page}, $template_page);
38
39         my $template_file=$pagesources{$template_page};
40         return sprintf(gettext("template %s not found"),
41                 htmllink($params{page}, $params{destpage}, "/".$template_page))
42                         unless defined $template_file;
43
44         my $template;
45         eval {
46                 $template=HTML::Template->new(
47                         filter => sub {
48                                 my $text_ref = shift;
49                                 $$text_ref=&Encode::decode_utf8($$text_ref);
50                                 chomp $$text_ref;
51                         },
52                         filename => srcfile($template_file),
53                         die_on_bad_params => 0,
54                         no_includes => 1,
55                         blind_cache => 1,
56                 );
57         };
58         if ($@) {
59                 error gettext("failed to process:")." $@"
60         }
61
62         $params{basename}=IkiWiki::basename($params{page});
63
64         foreach my $param (keys %params) {
65                 my $value=IkiWiki::preprocess($params{page}, $params{destpage},
66                           IkiWiki::filter($params{page}, $params{destpagea},
67                           $params{$param}), $scan);
68                 if ($template->query(name => $param)) {
69                         $template->param($param =>
70                                 IkiWiki::htmlize($params{page}, $params{destpage},
71                                         pagetype($pagesources{$params{page}}),
72                                         $value));
73                 }
74                 if ($template->query(name => "raw_$param")) {
75                         $template->param("raw_$param" => $value);
76                 }
77         }
78
79         return IkiWiki::preprocess($params{page}, $params{destpage},
80                IkiWiki::filter($params{page}, $params{destpage},
81                $template->output), $scan);
82 }
83
84 1