summaryrefslogtreecommitdiff
path: root/IkiWiki/Plugin/meta.pm
blob: ac8890795fb8eadf435ff9508682feaacfa8227e (plain)
  1. #!/usr/bin/perl
  2. # Ikiwiki metadata plugin.
  3. package IkiWiki::Plugin::meta;
  4. use warnings;
  5. use strict;
  6. use IkiWiki 2.00;
  7. my %meta;
  8. my %title;
  9. my %permalink;
  10. my %author;
  11. my %authorurl;
  12. my %license;
  13. my %copyright;
  14. sub import { #{{{
  15. hook(type => "preprocess", id => "meta", call => \&preprocess, scan => 1);
  16. hook(type => "filter", id => "meta", call => \&filter);
  17. hook(type => "pagetemplate", id => "meta", call => \&pagetemplate);
  18. } # }}}
  19. sub filter (@) { #{{{
  20. my %params=@_;
  21. $meta{$params{page}}='';
  22. return $params{content};
  23. } # }}}
  24. sub scrub ($) { #{{{
  25. if (IkiWiki::Plugin::htmlscrubber->can("sanitize")) {
  26. return IkiWiki::Plugin::htmlscrubber::sanitize(content => shift);
  27. }
  28. else {
  29. return shift;
  30. }
  31. } #}}}
  32. sub preprocess (@) { #{{{
  33. if (! @_) {
  34. return "";
  35. }
  36. my %params=@_;
  37. my $key=shift;
  38. my $value=$params{$key};
  39. delete $params{$key};
  40. my $page=$params{page};
  41. delete $params{page};
  42. my $destpage=$params{destpage};
  43. delete $params{destpage};
  44. delete $params{preview};
  45. eval q{use HTML::Entities};
  46. # Always dencode, even if encoding later, since it might not be
  47. # fully encoded.
  48. $value=decode_entities($value);
  49. if ($key eq 'link') {
  50. if (%params) {
  51. $meta{$page}.=scrub("<link href=\"".encode_entities($value)."\" ".
  52. join(" ", map {
  53. encode_entities($_)."=\"".encode_entities(decode_entities($params{$_}))."\""
  54. } keys %params).
  55. " />\n");
  56. }
  57. else {
  58. # hidden WikiLink
  59. push @{$links{$page}}, $value;
  60. }
  61. }
  62. elsif ($key eq 'redir') {
  63. my $safe=0;
  64. if ($value !~ /^\w+:\/\//) {
  65. my $link=bestlink($page, $value);
  66. if (! length $link) {
  67. return "[[meta ".gettext("redir page not found")."]]";
  68. }
  69. $value=urlto($link, $destpage);
  70. $safe=1;
  71. }
  72. else {
  73. $value=encode_entities($value);
  74. }
  75. my $delay=int(exists $params{delay} ? $params{delay} : 0);
  76. my $redir="<meta http-equiv=\"refresh\" content=\"$delay; URL=$value\">";
  77. if (! $safe) {
  78. $redir=scrub($redir);
  79. }
  80. $meta{$page}.=$redir;
  81. }
  82. elsif ($key eq 'title') {
  83. $title{$page}=HTML::Entities::encode_numeric($value);
  84. }
  85. elsif ($key eq 'permalink') {
  86. $permalink{$page}=$value;
  87. $meta{$page}.=scrub("<link rel=\"bookmark\" href=\"".encode_entities($value)."\" />\n");
  88. }
  89. elsif ($key eq 'date') {
  90. eval q{use Date::Parse};
  91. if (! $@) {
  92. my $time = str2time($value);
  93. $IkiWiki::pagectime{$page}=$time if defined $time;
  94. }
  95. }
  96. elsif ($key eq 'stylesheet') {
  97. my $rel=exists $params{rel} ? $params{rel} : "alternate stylesheet";
  98. my $title=exists $params{title} ? $params{title} : $value;
  99. # adding .css to the value prevents using any old web
  100. # editable page as a stylesheet
  101. my $stylesheet=bestlink($page, $value.".css");
  102. if (! length $stylesheet) {
  103. return "[[meta ".gettext("stylesheet not found")."]]";
  104. }
  105. $meta{$page}.='<link href="'.urlto($stylesheet, $page).
  106. '" rel="'.encode_entities($rel).
  107. '" title="'.encode_entities($title).
  108. "\" type=\"text/css\" />\n";
  109. }
  110. elsif ($key eq 'openid') {
  111. if (exists $params{server}) {
  112. $meta{$page}.='<link href="'.encode_entities($params{server}).
  113. "\" rel=\"openid.server\" />\n";
  114. }
  115. $meta{$page}.='<link href="'.encode_entities($value).
  116. "\" rel=\"openid.delegate\" />\n";
  117. }
  118. elsif ($key eq 'license') {
  119. $meta{$page}.="<link rel=\"license\" href=\"#page_license\" />\n";
  120. $license{$page}=$value;
  121. }
  122. elsif ($key eq 'copyright') {
  123. $meta{$page}.="<link rel=\"copyright\" href=\"#page_copyright\" />\n";
  124. $copyright{$page}=$value;
  125. }
  126. else {
  127. $meta{$page}.=scrub("<meta name=\"".encode_entities($key).
  128. "\" content=\"".encode_entities($value)."\" />\n");
  129. if ($key eq 'author') {
  130. $author{$page}=$value;
  131. }
  132. elsif ($key eq 'authorurl') {
  133. $authorurl{$page}=$value;
  134. }
  135. }
  136. return "";
  137. } # }}}
  138. sub pagetemplate (@) { #{{{
  139. my %params=@_;
  140. my $page=$params{page};
  141. my $destpage=$params{destpage};
  142. my $template=$params{template};
  143. $template->param(meta => $meta{$page})
  144. if exists $meta{$page} && $template->query(name => "meta");
  145. if (exists $title{$page} && $template->query(name => "title")) {
  146. $template->param(title => $title{$page});
  147. $template->param(title_overridden => 1);
  148. }
  149. $template->param(permalink => $permalink{$page})
  150. if exists $permalink{$page} && $template->query(name => "permalink");
  151. $template->param(author => $author{$page})
  152. if exists $author{$page} && $template->query(name => "author");
  153. $template->param(authorurl => $authorurl{$page})
  154. if exists $authorurl{$page} && $template->query(name => "authorurl");
  155. if ($page ne $destpage &&
  156. ((exists $license{$page} && ! exists $license{$destpage}) ||
  157. (exists $copyright{$page} && ! exists $copyright{$destpage}))) {
  158. # Force a scan of the destpage to get its copyright/license
  159. # info. If the info is declared after an inline, it will
  160. # otherwise not be available at this point.
  161. IkiWiki::scan($pagesources{$destpage});
  162. }
  163. if (exists $license{$page} && $template->query(name => "license") &&
  164. ($page eq $destpage || ! exists $license{$destpage} ||
  165. $license{$page} ne $license{$destpage})) {
  166. $template->param(license => IkiWiki::linkify($page, $destpage, $license{$page}));
  167. }
  168. if (exists $copyright{$page} && $template->query(name => "copyright") &&
  169. ($page eq $destpage || ! exists $copyright{$destpage} ||
  170. $copyright{$page} ne $copyright{$destpage})) {
  171. $template->param(copyright => IkiWiki::linkify($page, $destpage, $copyright{$page}));
  172. }
  173. } # }}}
  174. 1