2006-08-23 07:41:07 +02:00
|
|
|
#!/usr/bin/perl
|
|
|
|
# Structured template plugin.
|
|
|
|
package IkiWiki::Plugin::template;
|
|
|
|
|
|
|
|
use warnings;
|
|
|
|
use strict;
|
2008-12-23 22:34:19 +01:00
|
|
|
use IkiWiki 3.00;
|
2006-08-23 07:41:07 +02:00
|
|
|
use Encode;
|
|
|
|
|
2008-12-17 21:22:16 +01:00
|
|
|
sub import {
|
2008-08-04 01:35:35 +02:00
|
|
|
hook(type => "getsetup", id => "template", call => \&getsetup);
|
2009-02-17 19:30:07 +01:00
|
|
|
hook(type => "preprocess", id => "template", call => \&preprocess,
|
|
|
|
scan => 1);
|
2008-12-17 21:22:16 +01:00
|
|
|
}
|
2006-08-23 07:41:07 +02:00
|
|
|
|
2008-12-17 21:22:16 +01:00
|
|
|
sub getsetup () {
|
2008-08-04 01:35:35 +02:00
|
|
|
return
|
|
|
|
plugin => {
|
|
|
|
safe => 1,
|
|
|
|
rebuild => undef,
|
2010-02-12 12:35:52 +01:00
|
|
|
section => "widget",
|
2008-08-04 01:35:35 +02:00
|
|
|
},
|
2008-12-17 21:22:16 +01:00
|
|
|
}
|
2008-08-04 01:35:35 +02:00
|
|
|
|
2008-12-17 21:22:16 +01:00
|
|
|
sub preprocess (@) {
|
2006-08-23 07:41:07 +02:00
|
|
|
my %params=@_;
|
|
|
|
|
2010-01-27 04:26:50 +01:00
|
|
|
# This needs to run even in scan mode, in order to process
|
|
|
|
# links and other metadata included via the template.
|
|
|
|
my $scan=! defined wantarray;
|
|
|
|
|
2006-08-23 07:41:07 +02:00
|
|
|
if (! exists $params{id}) {
|
2008-07-13 21:05:34 +02:00
|
|
|
error gettext("missing id parameter")
|
2006-08-23 07:41:07 +02:00
|
|
|
}
|
|
|
|
|
2010-04-23 21:23:34 +02:00
|
|
|
# The bare id is used, so a page templates/$id can be used as
|
2010-04-23 20:45:48 +02:00
|
|
|
# the template.
|
2006-11-06 00:44:20 +01:00
|
|
|
my $template;
|
|
|
|
eval {
|
2010-04-23 20:45:48 +02:00
|
|
|
$template=template_depends($params{id}, $params{page},
|
|
|
|
blind_cache => 1);
|
2006-11-06 00:44:20 +01:00
|
|
|
};
|
|
|
|
if ($@) {
|
protect $@ whenever a block using $@ is non-trivial
As noted in the Try::Tiny man page, eval/$@ can be quite awkward in
corner cases, because $@ has the same properties and problems as C's
errno. While writing a regression test for definetemplate
in which it couldn't find an appropriate template, I received
<span class="error">Error: failed to process template
<span class="createlink">deftmpl</span> </span>
instead of the intended
<span class="error">Error: failed to process template
<span class="createlink">deftmpl</span> template deftmpl not
found</span>
which turned out to be because the "catch"-analogous block called
gettext before it used $@, and gettext can call define_gettext,
which uses eval.
This commit alters all current "catch"-like blocks that use $@, except
those that just do trivial things with $@ (string interpolation, string
concatenation) and call a function (die, error, print, etc.)
2014-02-21 18:06:36 +01:00
|
|
|
# gettext can clobber $@
|
|
|
|
my $error = $@;
|
2010-09-27 21:47:14 +02:00
|
|
|
error sprintf(gettext("failed to process template %s"),
|
2010-04-23 20:45:48 +02:00
|
|
|
htmllink($params{page}, $params{destpage},
|
protect $@ whenever a block using $@ is non-trivial
As noted in the Try::Tiny man page, eval/$@ can be quite awkward in
corner cases, because $@ has the same properties and problems as C's
errno. While writing a regression test for definetemplate
in which it couldn't find an appropriate template, I received
<span class="error">Error: failed to process template
<span class="createlink">deftmpl</span> </span>
instead of the intended
<span class="error">Error: failed to process template
<span class="createlink">deftmpl</span> template deftmpl not
found</span>
which turned out to be because the "catch"-analogous block called
gettext before it used $@, and gettext can call define_gettext,
which uses eval.
This commit alters all current "catch"-like blocks that use $@, except
those that just do trivial things with $@ (string interpolation, string
concatenation) and call a function (die, error, print, etc.)
2014-02-21 18:06:36 +01:00
|
|
|
"/templates/$params{id}"))." $error";
|
2006-11-06 00:44:20 +01:00
|
|
|
}
|
2006-08-23 07:41:07 +02:00
|
|
|
|
2008-07-10 21:25:05 +02:00
|
|
|
$params{basename}=IkiWiki::basename($params{page});
|
|
|
|
|
2006-08-23 07:41:07 +02:00
|
|
|
foreach my $param (keys %params) {
|
2010-01-27 04:26:50 +01:00
|
|
|
my $value=IkiWiki::preprocess($params{page}, $params{destpage},
|
remove unnecessary and troublesome filter calls
This better defines what the filter hook is passed, to only be the raw,
complete text of a page. Not some snippet, or data read in from an
unrelated template.
Several plugins that filtered text that originates from an (already
filtered) page were modified not to do that. Note that this was not
done very consistently before; other plugins that receive text from a
page called preprocess on it w/o first calling filter.
The template plugin gets text from elsewhere, and was also changed not to
filter it. That leads to one known regression -- the embed plugin cannot
be used to embed stuff in templates now. But that plugin is deprecated
anyway.
Later we may want to increase the coverage of what is filtered. Perhaps
a good goal would be to allow writing a filter plugin that filters
out unwanted words, from any input. We're not there yet; not only
does the template plugin load unfiltered text from its templates now,
but so can the table plugin, and other plugins that use templates (like
inline!). I think we can cross that bridge when we come to it. If I wanted
such a censoring plugin, I'd probably make it use a sanitize hook instead,
for the better coverage.
For now I am concentrating on the needs of the two non-deprecated users
of filter. This should fix bugs/po_vs_templates, and it probably fixes
an obscure bug around txt's use of filter for robots.txt.
2010-07-04 21:00:51 +02:00
|
|
|
$params{$param}, $scan);
|
2008-01-09 20:17:25 +01:00
|
|
|
if ($template->query(name => $param)) {
|
2010-04-24 07:13:58 +02:00
|
|
|
my $htmlvalue=IkiWiki::htmlize($params{page}, $params{destpage},
|
2008-01-09 20:17:25 +01:00
|
|
|
pagetype($pagesources{$params{page}}),
|
2010-04-24 07:13:58 +02:00
|
|
|
$value);
|
|
|
|
chomp $htmlvalue;
|
|
|
|
$template->param($param => $htmlvalue);
|
2008-01-09 20:17:25 +01:00
|
|
|
}
|
|
|
|
if ($template->query(name => "raw_$param")) {
|
2010-04-24 07:13:58 +02:00
|
|
|
chomp $value;
|
2010-01-27 04:26:50 +01:00
|
|
|
$template->param("raw_$param" => $value);
|
2008-01-09 20:17:25 +01:00
|
|
|
}
|
2006-08-23 07:41:07 +02:00
|
|
|
}
|
|
|
|
|
2008-01-09 20:17:25 +01:00
|
|
|
return IkiWiki::preprocess($params{page}, $params{destpage},
|
remove unnecessary and troublesome filter calls
This better defines what the filter hook is passed, to only be the raw,
complete text of a page. Not some snippet, or data read in from an
unrelated template.
Several plugins that filtered text that originates from an (already
filtered) page were modified not to do that. Note that this was not
done very consistently before; other plugins that receive text from a
page called preprocess on it w/o first calling filter.
The template plugin gets text from elsewhere, and was also changed not to
filter it. That leads to one known regression -- the embed plugin cannot
be used to embed stuff in templates now. But that plugin is deprecated
anyway.
Later we may want to increase the coverage of what is filtered. Perhaps
a good goal would be to allow writing a filter plugin that filters
out unwanted words, from any input. We're not there yet; not only
does the template plugin load unfiltered text from its templates now,
but so can the table plugin, and other plugins that use templates (like
inline!). I think we can cross that bridge when we come to it. If I wanted
such a censoring plugin, I'd probably make it use a sanitize hook instead,
for the better coverage.
For now I am concentrating on the needs of the two non-deprecated users
of filter. This should fix bugs/po_vs_templates, and it probably fixes
an obscure bug around txt's use of filter for robots.txt.
2010-07-04 21:00:51 +02:00
|
|
|
$template->output, $scan);
|
2008-12-17 21:22:16 +01:00
|
|
|
}
|
2006-08-23 07:41:07 +02:00
|
|
|
|
|
|
|
1
|