Copy 'template.pm' re-write from website
authorhttps://www.google.com/accounts/o8/id?id=AItOawlqWSY9PNYRysA9vrU-JiQh7-s7q6SOcIE <Fergus@web>
Thu, 15 Mar 2012 22:52:13 +0000 (18:52 -0400)
committeradmin <admin@branchable.com>
Thu, 15 Mar 2012 22:52:13 +0000 (18:52 -0400)
doc/todo/allow_TMPL__95__LOOP_in_template_directives.mdwn [new file with mode: 0644]

diff --git a/doc/todo/allow_TMPL__95__LOOP_in_template_directives.mdwn b/doc/todo/allow_TMPL__95__LOOP_in_template_directives.mdwn
new file mode 100644 (file)
index 0000000..a8d1005
--- /dev/null
@@ -0,0 +1,258 @@
+[[!tag patch]]
+
+[[!templte id="note" text="""
+Simply copied this from my website
+[[http://www.camco.ie/code/ikiwiki,3.20120202,20120313a/]]
+feel free to reformat / delete"""]]
+
+The following re-write allows for multiple definitions of the
+same tag value in a template definition.  This, in turn, allows
+us to use TMPL_LOOPS in our template directives; all-be-it in a
+rather limited way.
+
+I would, personally, only use this feature for very basic loops
+and, although nested loops *might* be possible (with a little
+more tinkering) it think any attempt would be better served by
+[[Kathyrn Anderson's|http://www.katspace.org/]] [[field et
+al.|http://ikiwiki.info/plugins/contrib/field/]] plugin.
+
+It *is* (primarily) intended to allow insertion of organised CSS
+blocks (i.e. `<div>`) through template directives (since i can't
+seem to get HTML and Markup to mix the way I want).
+
+[[!template id="note" text="""
+Apologies for the re-write.  I struggle reading perl code that
+I didn't write and (probably too often) re-format to reduce my
+head-aches.  Anyway it didn't make sense to post the patch since
+everything's changed now.
+"""]]
+
+# `lib/perl5/IkiWiki/Plugin/template.pm`
+
+[[!format perl """
+
+       #!/usr/bin/perl
+       # Structured template plugin.
+       package IkiWiki::Plugin::template ;
+
+       use warnings ;
+       use strict ;
+       use IkiWiki 3.00 ;
+       use Encode ;
+
+       sub mktmpl_hash( $ ; $ ; @ ) ;
+                               # declare to supress warning in recursive call
+       sub mktmpl_hash( $ ; $ ; @ )
+                               # make hash for the template, filling
+                               # values from the supplied params
+       {
+               my $template = shift( @_ )
+                               || error( "mktmpl_hash: no template provided" ) ;
+               my $param_src = shift( @_ )
+                               || error( "mktmpl_hash: no parameters" ) ;
+
+               my $path ;
+               if( $#_ > 0 )
+               {
+                       $path = [ @_ ] ;
+               } else {
+                       $path = shift(@_) || [] ;
+               } ;
+
+               my %params ;
+
+               my @path_vars ;
+               if( $#{$path} < 0 )
+               {
+                       @path_vars = $template->query() ;
+               } else {
+                       @path_vars = $template->query( loop => $path ) ;
+               } ;
+
+               foreach my $var ( @path_vars )
+               {
+                       push( @{$path}, $var ) ;
+                       my $param_type = $template->query( name => $path ) ;
+                       if( $param_type eq 'VAR' )
+                       {
+                               my @var_path = split( /_/, $var ) ;
+                               if( $var_path[0] ne '' )
+                               {
+                                       $path->[-1] = join( '_', @var_path[1..$#var_path] )
+                                               if( $var_path[0] eq 'raw' ) ;
+                                       $params{$var} = shift( @{$param_src->{$path->[-1]}} )
+                                                       || return(undef) ;
+                               } ;
+                       } elsif( $param_type eq 'LOOP' )
+                       {
+                               $params{$var} = [] ;
+                               push( @{$params{$var}}, $_ )
+                                       while( $_ = mktmpl_hash($template,$param_src,$path) ) ;
+                       } ;
+                       pop( @{$path} ) ;
+               } ; 
+               return( \%params ) ;
+       } ;
+
+       sub proc_tmpl_hash( $ ; $ ; $ ; $ ) ;
+                               # declare to supress warning in recursive call
+       sub proc_tmpl_hash( $ ; $ ; $ ; $ )
+                               # walk the hash, preprocess and
+                               # convert to html
+       {
+               my $tmpl_hash = shift( @_ ) ;
+               my $page = shift( @_ ) ;
+               my $destpage = shift( @_ ) ;
+               my $scan = shift( @_ ) ;
+               foreach my $key ( keys(%{$tmpl_hash}) )
+               {
+                       unless( ref($tmpl_hash->{$key}) )
+                                               # here we assume that
+                                               # any reference is an
+                                               # array and allow it to
+                                               # fail if that's false
+                       {
+                               $tmpl_hash->{$key} =
+                                               IkiWiki::preprocess(
+                                                               $page,
+                                                               $destpage,
+                                                               $tmpl_hash->{$key},
+                                                               $scan ) ;
+                               my @key_path = split( /_/, $key ) ;
+                               $tmpl_hash->{$key} =
+                                               IkiWiki::htmlize(
+                                                               $page,
+                                                               $destpage,
+                                                               pagetype($pagesources{$page}),
+                                                               $tmpl_hash->{$key}, )
+                                       unless( $key_path[0] eq 'raw' ) ;
+                       } else {
+                               proc_tmpl_hash( $_, $page, $destpage, $scan )
+                                       foreach( @{$tmpl_hash->{$key}} ) ;
+                       } ;
+               } ;
+       } ;
+
+       # "standard" ikiwiki definitions / hooks
+
+       sub import
+       {
+               hook( type => "getsetup",
+                               id => "template",
+                               call => \&getsetup ) ;
+               hook( type => "preprocess",
+                               id => "template",
+                               call => \&preprocess,
+                               scan => 1 ) ;
+       } ;
+
+       sub getsetup()
+       {
+               return(
+                               plugin => {
+                                       safe => 1,
+                                       rebuild => undef,
+                                       section => "widget",
+                               }, ) ;
+       } ;
+
+       sub preprocess( @ )
+       {
+       # first process arguments into arrays of values
+               my %params ;
+
+               my( $key, $value ) ;
+               while( ($key,$value)=splice(@_,0,2) )
+               {
+                       if( exists($params{$key}) )
+                       {
+                               push( @{$params{$key}}, $value ) ;
+                       } else {
+                               $params{$key} = [ $value ] ;
+                       } ;
+               } ;
+
+       # set context
+               my $scan = ! defined( wantarray() ) ;
+                                       # This needs to run even in scan
+                                       # mode, in order to process links
+                                       # and other metadata included via
+                                       # the template.
+
+       # check for critical values
+               if( ! exists($params{id}) )
+               {
+                       error( gettext("missing id parameter") ) ;
+               } ;
+
+       # set some convenience variables
+               my $id = $params{id}->[$#{$params{id}}] ;
+               my $page = $params{page}->[$#{$params{page}}] ;
+               my $destpage = $params{destpage}->[$#{$params{destpage}}] ;
+       # ... and an essential one for the production pass
+               $params{basename} = IkiWiki::basename($page) ;
+
+       # load the template
+               my $template ;
+               eval {
+                       $template =
+                                       template_depends( $id, $page,
+                                                       blind_cache=>1 ) ;
+                                               # The bare id is used, so
+                                               # a page templates/$id can
+                                               # be used as the template.
+               } ;
+               if( $@ )
+               {
+                       error(
+                                       sprintf(
+                                                       gettext("failed to process template %s"),
+                                                       htmllink(
+                                                                       $page,
+                                                                       $destpage,
+                                                                       "/templates/$id")
+                                                       )." $@"
+                                       ) ;
+               } ;
+
+       # create and process the parameters
+               my $tmpl_hash = mktmpl_hash( $template, \%params ) ;
+               proc_tmpl_hash( $tmpl_hash, $page, $destpage, $scan ) ;
+       # ... and load the template with the values
+               $template->param( $tmpl_hash ) ;
+
+       # return the processed page chunk
+               return( IkiWiki::preprocess($page,
+                                               $destpage,
+                                               $template->output(),$scan)
+                               ) ;
+       } ;
+
+       1 ;
+
+"""]]
+
+## sample template
+
+       # <TMPL_VAR HEADER0>
+
+       <table>
+       <TMPL_LOOP TEST0>
+       <tr>
+               <td><TMPL_VAR DATA0></td>
+               <td><TMPL_VAR DATA1></td>
+       </tr>
+       </TMPL_LOOP>
+       </table>
+
+## sample iki page
+
+       \[[!meta title="this is my loops page"]]
+
+       \[[!template id="loops"
+       header0="this is a table"
+       data0="cell0:0"
+       data1="cell0:1"
+       data0="cell1:0"
+       data0="cell1:1"
+       ]]