3 [[!template id="note" text="""
4 Simply copied this from my website
5 [[http://www.camco.ie/code/ikiwiki,3.20120202,20120313a/]]
6 feel free to reformat / delete"""]]
8 The following re-write allows for multiple definitions of the
9 same tag value in a [[plugins/template]] definition. This, in turn, allows
10 us to use TMPL_LOOPS in our [[ikiwiki/directive/template]] directives; all-be-it in a
13 > I'm willing to consider such a feature, but it needs to be presented in
14 > the form of a patch that is reviewable, not a gratuitous rewrite.
17 >> Yes, my apologies for that. The two worker functions `mktmpl_hash`
18 and `proc_tmpl_hash` are new. The `preprocess` function then starts
19 by arranging the parameters into an array. This array is passed to the
20 `mktmpl_hash` and it creates a hash, suitable for passing into the
21 HTML::Template directly. The `proc_tmpl_hash` then walks the hash
22 structure and processes the parameters.
24 >> I know ... you weren't looking for an explanation, just a patch
25 ... totally understand. Point I'm trying to make, it's a 90% re-write
26 anyway (and my `style(8)` will probably piss most people off).
28 >> Anyway, would love to contribute so will try to get to doing this
29 "correctly" and post as a patch.
31 I would, personally, only use this feature for very basic loops
32 and, although nested loops *might* be possible (with a little
33 more tinkering) it think any attempt would be better served by
34 [[Kathyrn Anderson's|http://www.katspace.org/]] [[field et
35 al.|http://ikiwiki.info/plugins/contrib/field/]] plugin.
37 It *is* (primarily) intended to allow insertion of organised CSS
38 blocks (i.e. `<div>`) through template directives (since i can't
39 seem to get HTML and Markup to mix the way I want).
41 [[!template id="note" text="""
42 Apologies for the re-write. I struggle reading perl code that
43 I didn't write and (probably too often) re-format to reduce my
44 head-aches. Anyway it didn't make sense to post the patch since
45 everything's changed now.
48 NB: this *should* be 100% backwards compatible.
50 # `lib/perl5/IkiWiki/Plugin/template.pm`
55 # Structured template plugin.
56 package IkiWiki::Plugin::template ;
63 sub mktmpl_hash( $ ; $ ; @ ) ;
64 # declare to supress warning in recursive call
65 sub mktmpl_hash( $ ; $ ; @ )
66 # make hash for the template, filling
67 # values from the supplied params
69 my $template = shift( @_ )
70 || error( "mktmpl_hash: no template provided" ) ;
71 my $param_src = shift( @_ )
72 || error( "mktmpl_hash: no parameters" ) ;
79 $path = shift(@_) || [] ;
87 @path_vars = $template->query() ;
89 @path_vars = $template->query( loop => $path ) ;
92 foreach my $var ( @path_vars )
94 push( @{$path}, $var ) ;
95 my $param_type = $template->query( name => $path ) ;
96 if( $param_type eq 'VAR' )
98 my @var_path = split( /_/, $var ) ;
99 if( $var_path[0] ne '' )
101 $path->[-1] = join( '_', @var_path[1..$#var_path] )
102 if( $var_path[0] eq 'raw' ) ;
103 $params{$var} = shift( @{$param_src->{$path->[-1]}} )
106 } elsif( $param_type eq 'LOOP' )
109 push( @{$params{$var}}, $_ )
110 while( $_ = mktmpl_hash($template,$param_src,$path) ) ;
117 sub proc_tmpl_hash( $ ; $ ; $ ; $ ) ;
118 # declare to supress warning in recursive call
119 sub proc_tmpl_hash( $ ; $ ; $ ; $ )
120 # walk the hash, preprocess and
123 my $tmpl_hash = shift( @_ ) ;
124 my $page = shift( @_ ) ;
125 my $destpage = shift( @_ ) ;
126 my $scan = shift( @_ ) ;
127 foreach my $key ( keys(%{$tmpl_hash}) )
129 unless( ref($tmpl_hash->{$key}) )
130 # here we assume that
131 # any reference is an
132 # array and allow it to
133 # fail if that's false
141 my @key_path = split( /_/, $key ) ;
146 pagetype($pagesources{$page}),
147 $tmpl_hash->{$key}, )
148 unless( $key_path[0] eq 'raw' ) ;
150 proc_tmpl_hash( $_, $page, $destpage, $scan )
151 foreach( @{$tmpl_hash->{$key}} ) ;
156 # "standard" ikiwiki definitions / hooks
160 hook( type => "getsetup",
162 call => \&getsetup ) ;
163 hook( type => "preprocess",
165 call => \&preprocess,
181 # first process arguments into arrays of values
185 while( ($key,$value)=splice(@_,0,2) )
187 if( exists($params{$key}) )
189 push( @{$params{$key}}, $value ) ;
191 $params{$key} = [ $value ] ;
196 my $scan = ! defined( wantarray() ) ;
197 # This needs to run even in scan
198 # mode, in order to process links
199 # and other metadata included via
202 # check for critical values
203 if( ! exists($params{id}) )
205 error( gettext("missing id parameter") ) ;
208 # set some convenience variables
209 my $id = $params{id}->[$#{$params{id}}] ;
210 my $page = $params{page}->[$#{$params{page}}] ;
211 my $destpage = $params{destpage}->[$#{$params{destpage}}] ;
212 # ... and an essential one for the production pass
213 $params{basename} = [ IkiWiki::basename($page) ] ;
219 template_depends( $id, $page,
221 # The bare id is used, so
222 # a page templates/$id can
223 # be used as the template.
229 gettext("failed to process template %s"),
238 # create and process the parameters
239 my $tmpl_hash = mktmpl_hash( $template, \%params ) ;
240 proc_tmpl_hash( $tmpl_hash, $page, $destpage, $scan ) ;
241 # ... and load the template with the values
242 $template->param( $tmpl_hash ) ;
244 # return the processed page chunk
245 return( IkiWiki::preprocess($page,
247 $template->output(),$scan)
262 <td><TMPL_VAR DATA0></td>
263 <td><TMPL_VAR DATA1></td>
270 \[[!meta title="this is my loops page"]]
272 \[[!template id="loops"
273 header0="this is a table"