Last active
December 11, 2015 10:38
-
-
Save anderbubble/4587864 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
package IkiWiki::Plugin::edittemplate; | |
use warnings; | |
use strict; | |
use IkiWiki 3.00; | |
use HTML::Template; | |
use Encode; | |
use UUID::Tiny ':std'; | |
sub import { | |
hook(type => "getsetup", id => "edittemplate", | |
call => \&getsetup); | |
hook(type => "needsbuild", id => "edittemplate", | |
call => \&needsbuild); | |
hook(type => "preprocess", id => "edittemplate", | |
call => \&preprocess); | |
hook(type => "formbuilder", id => "edittemplate", | |
call => \&formbuilder); | |
} | |
sub getsetup () { | |
return | |
plugin => { | |
safe => 1, | |
rebuild => undef, | |
section => "web", | |
}, | |
} | |
sub needsbuild (@) { | |
my $needsbuild=shift; | |
foreach my $page (keys %pagestate) { | |
if (exists $pagestate{$page}{edittemplate}) { | |
if (exists $pagesources{$page} && | |
grep { $_ eq $pagesources{$page} } @$needsbuild) { | |
# remove state, it will be re-added | |
# if the preprocessor directive is still | |
# there during the rebuild | |
delete $pagestate{$page}{edittemplate}; | |
} | |
} | |
} | |
return $needsbuild; | |
} | |
sub preprocess (@) { | |
my %params=@_; | |
return "" if $params{page} ne $params{destpage}; | |
if (! exists $params{template} || ! length($params{template})) { | |
error gettext("template not specified") | |
} | |
if (! exists $params{match} || ! length($params{match})) { | |
error gettext("match not specified") | |
} | |
my $link=linkpage($params{template}); | |
add_depends($params{page}, $link, deptype("presence")); | |
my $bestlink=bestlink($params{page}, $link); | |
if (! length $bestlink) { | |
add_depends($params{page}, "templates/$link", deptype("presence")); | |
$link="/templates/".$link; | |
$bestlink=bestlink($params{page}, $link); | |
} | |
$pagestate{$params{page}}{edittemplate}{$params{match}}{template}=$bestlink; | |
$pagestate{$params{page}}{edittemplate}{$params{match}}{params}=\%params; | |
return "" if ($params{silent} && IkiWiki::yesno($params{silent})) && | |
length $bestlink; | |
return sprintf(gettext("edittemplate %s registered for %s"), | |
htmllink($params{page}, $params{destpage}, $link), | |
$params{match}); | |
} | |
sub formbuilder (@) { | |
my %params=@_; | |
my $form=$params{form}; | |
return if $form->field("do") ne "create" || | |
(defined $form->field("editcontent") && length $form->field("editcontent")); | |
my $page=$form->field("page"); | |
# The tricky bit here is that $page is probably just the base | |
# page name, without any subdir, but the pagespec for a template | |
# probably does include the subdir (ie, "bugs/*"). We don't know | |
# what subdir the user will pick to put the page in. So, try them | |
# all, starting with the one that was made default. | |
my @page_locs=$page; | |
foreach my $field ($form->field) { | |
if ($field eq 'page') { | |
@page_locs=$field->def_value; | |
# FormBuilder is on the bad crack. See #551499 | |
my @options=map { ref $_ ? @$_ : $_ } $field->options; | |
push @page_locs, @options; | |
} | |
} | |
foreach my $p (@page_locs) { | |
foreach my $registering_page (keys %pagestate) { | |
if (exists $pagestate{$registering_page}{edittemplate}) { | |
foreach my $pagespec (sort keys %{$pagestate{$registering_page}{edittemplate}}) { | |
if (pagespec_match($p, $pagespec, location => $registering_page)) { | |
my $template=$pagestate{$registering_page}{edittemplate}{$pagespec}{template}; | |
my $template_params=$pagestate{$registering_page}{edittemplate}{$pagespec}{params}; | |
$form->field(name => "editcontent", | |
value => filltemplate($template, $page, $template_params)); | |
my $type=pagetype($pagesources{$template}) | |
if $pagesources{$template}; | |
$form->field(name => "type", | |
value => $type) | |
if defined $type; | |
return; | |
} | |
} | |
} | |
} | |
} | |
} | |
sub filltemplate ($$) { | |
my $template_page=shift; | |
my $page=shift; | |
my $params=shift; | |
my $template; | |
eval { | |
# force page name absolute so it doesn't look in templates/ | |
$template=template("/".$template_page); | |
}; | |
if ($@) { | |
# Indicate that the earlier preprocessor directive set | |
# up a template that doesn't work. | |
return "[[!pagetemplate ".gettext("failed to process template:")." $@]]"; | |
} | |
$template->param(name => $page); | |
if ($params->{uuid} && IkiWiki::yesno($params->{uuid})) { | |
my $uuid = create_uuid_as_string(); | |
$template->param(uuid => $uuid); | |
} | |
if ($params->{date} && IkiWiki::yesno($params->{date})) { | |
my $now_string = localtime(); | |
$template->param(date => $now_string); | |
} | |
return $template->output; | |
} | |
1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment