ikiwiki (3.20130711) unstable; urgency=low
[ikiwiki.git] / doc / todo / Extensible_inlining.mdwn
1 Here's an idea with [[patch]] for extending inline in two directions:
2
3 1. Permit the content-fetching function to return undef to skip a page. The limiting of @list to a set size is performed after that filtering.
4 2. Permit other directive plugins to pass a function to generate content via an inliner_ parameter. The current patch doesn't try to remove that key from the parameters, so hilarity might ensue if someone is too clever. I suppose I should fix that... My *intent* is that other, custom directives can add inliner_.
5
6 The diff looks large because the first requires switching some loops.
7
8 I'm using this along with a custom BibTeX formatter (one item per file) to generate larger pages and tiny listings. I still need to hammer the templates for that, but I think that's possible without further patches.
9
10 (Setting up a git branch for a single plugin is a pain, but I can if necessary. I also could separate this into some sequence rather than all at once, but I won't have time for a week or two.)
11
12 -- [[JasonRiedy]]
13
14 <pre><code>
15 --- /home/ejr/src/git.ikiwiki.info/IkiWiki/Plugin/inline.pm     2011-03-05 14:18:30.261293808 -0500
16 +++ inline.pm   2011-03-06 21:44:18.887903638 -0500
17 @@ -185,6 +185,7 @@
18         }
19  
20         my @list;
21 +       my $num = 0;
22  
23         if (exists $params{pagenames}) {
24                 foreach my $p (qw(sort pages)) {
25 @@ -213,23 +214,121 @@
26                 if ($params{feedshow} && $num < $params{feedshow} && $num > 0) {
27                         $num=$params{feedshow};
28                 }
29 -               if ($params{skip} && $num) {
30 -                       $num+=$params{skip};
31 -               }
32  
33                 @list = pagespec_match_list($params{page}, $params{pages},
34                         deptype => deptype($quick ? "presence" : "content"),
35                         filter => sub { $_[0] eq $params{page} },
36                         sort => exists $params{sort} ? $params{sort} : "age",
37                         reverse => yesno($params{reverse}),
38 -                       ($num ? (num => $num) : ()),
39                 );
40         }
41  
42         if (exists $params{skip}) {
43                 @list=@list[$params{skip} .. $#list];
44         }
45 +
46 +       if ($params{show} && $params{show} > $num) {
47 +               $num = $params{show}
48 +       }
49 +
50 +       my $ret="";
51 +       my @displist;
52 +       if ($feedonly) {
53 +               @displist = @list;
54 +       } else {
55 +               my $template;
56 +               if (! $raw) {
57 +                       # cannot use wiki pages as templates; template not sanitized due to
58 +                       # format hook hack
59 +                       eval {
60 +                               $template=template_depends($params{template}.".tmpl", $params{page},
61 +                                       blind_cache => 1);
62 +                       };
63 +                       if ($@) {
64 +                               error sprintf(gettext("failed to process template %s"), $params{template}.".tmpl").": $@";
65 +                       }
66 +               }
67 +               my $needcontent=$raw || (!($archive && $quick) && $template->query(name => 'content'));
68 +
69 +               foreach my $page (@list) {
70 +                       last if ($num && scalar @displist >= $num);
71 +                       my $file = $pagesources{$page};
72 +                       my $type = pagetype($file);
73 +                       if (! $raw) {
74 +                               # Get the content before populating the
75 +                               # template, since getting the content uses
76 +                               # the same template if inlines are nested.
77 +                               if ($needcontent) {
78 +                                       my $content;
79 +                                       if (exists $params{inliner_} && defined $params{inliner_}) {
80 +                                               $content = &{$params{inliner_}}($page, $template, %params);
81 +                                       } else {
82 +                                               $content=get_inline_content($page, $params{destpage});
83 +                                       }
84 +                                       next if !defined $content;
85 +                                       $template->param(content => $content);
86 +                                       push @displist, $page;
87 +                               }
88 +                               $template->param(pageurl => urlto($page, $params{destpage}));
89 +                               $template->param(inlinepage => $page);
90 +                               $template->param(title => pagetitle(basename($page)));
91 +                               $template->param(ctime => displaytime($pagectime{$page}, $params{timeformat}, 1));
92 +                               $template->param(mtime => displaytime($pagemtime{$page}, $params{timeformat}));
93 +                               $template->param(first => 1) if $page eq $list[0];
94 +                               $template->param(last => 1) if ($num && scalar @displist == $num);
95 +                               $template->param(html5 => $config{html5});
96         
97 +                               if ($actions) {
98 +                                       my $file = $pagesources{$page};
99 +                                       my $type = pagetype($file);
100 +                                       if ($config{discussion}) {
101 +                                               if ($page !~ /.*\/\Q$config{discussionpage}\E$/i &&
102 +                                                   (length $config{cgiurl} ||
103 +                                                    exists $pagesources{$page."/".lc($config{discussionpage})})) {
104 +                                                       $template->param(have_actions => 1);
105 +                                                       $template->param(discussionlink =>
106 +                                                               htmllink($page,
107 +                                                                       $params{destpage},
108 +                                                                       $config{discussionpage},
109 +                                                                       noimageinline => 1,
110 +                                                                       forcesubpage => 1));
111 +                                               }
112 +                                       }
113 +                                       if (length $config{cgiurl} &&
114 +                                           defined $type &&
115 +                                           IkiWiki->can("cgi_editpage")) {
116 +                                               $template->param(have_actions => 1);
117 +                                               $template->param(editurl => cgiurl(do => "edit", page => $page));
118 +
119 +                                       }
120 +                               }
121 +       
122 +                               run_hooks(pagetemplate => sub {
123 +                                       shift->(page => $page, destpage => $params{destpage},
124 +                                               template => $template,);
125 +                               });
126 +       
127 +                               $ret.=$template->output;
128 +                               $template->clear_params;
129 +                       }
130 +                       else {
131 +                               if (defined $type) {
132 +                                       $ret.="\n".
133 +                                             linkify($page, $params{destpage},
134 +                                             preprocess($page, $params{destpage},
135 +                                             filter($page, $params{destpage},
136 +                                             readfile(srcfile($file)))));
137 +                               }
138 +                               else {
139 +                                       $ret.="\n".
140 +                                             readfile(srcfile($file));
141 +                               }
142 +                               push @displist, $page;
143 +                       }
144 +               }
145 +       }
146 +       @list = @displist;
147 +
148         my @feedlist;
149         if ($feeds) {
150                 if (exists $params{feedshow} &&
151 @@ -241,10 +340,6 @@
152                 }
153         }
154         
155 -       if ($params{show} && @list > $params{show}) {
156 -               @list=@list[0..$params{show} - 1];
157 -       }
158 -
159         if ($feeds && exists $params{feedpages}) {
160                 @feedlist = pagespec_match_list(
161                         $params{page}, "($params{pages}) and ($params{feedpages})",
162 @@ -302,8 +397,6 @@
163                 }
164         }
165  
166 -       my $ret="";
167 -
168         if (length $config{cgiurl} && ! $params{preview} && (exists $params{rootpage} ||
169             (exists $params{postform} && yesno($params{postform}))) &&
170             IkiWiki->can("cgi_editpage")) {
171 @@ -355,91 +448,7 @@
172                 }
173                 $ret.=$linktemplate->output;
174         }
175 -       
176 -       if (! $feedonly) {
177 -               my $template;
178 -               if (! $raw) {
179 -                       # cannot use wiki pages as templates; template not sanitized due to
180 -                       # format hook hack
181 -                       eval {
182 -                               $template=template_depends($params{template}.".tmpl", $params{page},
183 -                                       blind_cache => 1);
184 -                       };
185 -                       if ($@) {
186 -                               error sprintf(gettext("failed to process template %s"), $params{template}.".tmpl").": $@";
187 -                       }
188 -               }
189 -               my $needcontent=$raw || (!($archive && $quick) && $template->query(name => 'content'));
190 -       
191 -               foreach my $page (@list) {
192 -                       my $file = $pagesources{$page};
193 -                       my $type = pagetype($file);
194 -                       if (! $raw) {
195 -                               if ($needcontent) {
196 -                                       # Get the content before populating the
197 -                                       # template, since getting the content uses
198 -                                       # the same template if inlines are nested.
199 -                                       my $content=get_inline_content($page, $params{destpage});
200 -                                       $template->param(content => $content);
201 -                               }
202 -                               $template->param(pageurl => urlto($page, $params{destpage}));
203 -                               $template->param(inlinepage => $page);
204 -                               $template->param(title => pagetitle(basename($page)));
205 -                               $template->param(ctime => displaytime($pagectime{$page}, $params{timeformat}, 1));
206 -                               $template->param(mtime => displaytime($pagemtime{$page}, $params{timeformat}));
207 -                               $template->param(first => 1) if $page eq $list[0];
208 -                               $template->param(last => 1) if $page eq $list[$#list];
209 -                               $template->param(html5 => $config{html5});
210 -       
211 -                               if ($actions) {
212 -                                       my $file = $pagesources{$page};
213 -                                       my $type = pagetype($file);
214 -                                       if ($config{discussion}) {
215 -                                               if ($page !~ /.*\/\Q$config{discussionpage}\E$/i &&
216 -                                                   (length $config{cgiurl} ||
217 -                                                    exists $pagesources{$page."/".lc($config{discussionpage})})) {
218 -                                                       $template->param(have_actions => 1);
219 -                                                       $template->param(discussionlink =>
220 -                                                               htmllink($page,
221 -                                                                       $params{destpage},
222 -                                                                       $config{discussionpage},
223 -                                                                       noimageinline => 1,
224 -                                                                       forcesubpage => 1));
225 -                                               }
226 -                                       }
227 -                                       if (length $config{cgiurl} &&
228 -                                           defined $type &&
229 -                                           IkiWiki->can("cgi_editpage")) {
230 -                                               $template->param(have_actions => 1);
231 -                                               $template->param(editurl => cgiurl(do => "edit", page => $page));
232  
233 -                                       }
234 -                               }
235 -       
236 -                               run_hooks(pagetemplate => sub {
237 -                                       shift->(page => $page, destpage => $params{destpage},
238 -                                               template => $template,);
239 -                               });
240 -       
241 -                               $ret.=$template->output;
242 -                               $template->clear_params;
243 -                       }
244 -                       else {
245 -                               if (defined $type) {
246 -                                       $ret.="\n".
247 -                                             linkify($page, $params{destpage},
248 -                                             preprocess($page, $params{destpage},
249 -                                             filter($page, $params{destpage},
250 -                                             readfile(srcfile($file)))));
251 -                               }
252 -                               else {
253 -                                       $ret.="\n".
254 -                                             readfile(srcfile($file));
255 -                               }
256 -                       }
257 -               }
258 -       }
259 -       
260         if ($feeds && ($emptyfeeds || @feedlist)) {
261                 if ($rss) {
262                         my $rssp=$feedbase."rss".$feednum;
263 </code></pre>