Only interpolate action tag content when defined.
[matthijs/upstream/blosxom-plugins.git] / general / interpolate_fancy
index a28880804b0d5e96b56ad4efee0e555df168a833..9eaf045219c4fef24b400a5630130ebddb2d9471 100644 (file)
@@ -2,12 +2,15 @@
 # Author: Rael Dornfest <rael@oreilly.com>, 
 # Modified by: Matthijs Kooijman <m.kooijman@student.utwente.nl>
 # and Barijaona Ramaholimihaso
-# Version: 2007-09-13
+# Version: 2007-09-27
 # Documentation: See the bottom of this file or type: 
 # perldoc interpolate_fancy
 
 package interpolate_fancy;
 
+use warnings;
+use strict;
+
 # --- Configurable variables -----
 
 # Do you want me to recursively interpolate into the story $title
@@ -49,7 +52,7 @@ sub _resolve_nested {
     my $display  = shift;
   
     while (1) {
-        if ($template !~ /(.*?)<\?(\!?\$\w+(?:::)?\w*)(?:\s+?(.+?))?>(.*)/s) {
+        if ($template !~ /(.*?)<\?(\!?\$\w+(?:::\w+)*)(?:\s+?(.+?))?>(.*)/s) {
             return $template; # No open tags, normal text
         }
        
@@ -96,22 +99,25 @@ sub _resolve_nested {
 
 
 sub interpolate {
-  return sub {
+  return \&interpolate_fancy::do_interpolate;
+}
+
+sub do_interpolate {
 
     package blosxom;
 
     # Halt recursive interpolation of story $body
     # by mangling interpolation tags (to be unmangled in a moment)
     unless ($recurse_into_story) {
-      $blosxom::title =~ s/<(\@|\??\$)/<#INTERPOLATE_FANCY_DEFANG#$1/gsi;
-      $blosxom::body =~ s/<(\@|\??\$)/<#INTERPOLATE_FANCY_DEFANG#$1/gsi;
+      $blosxom::title =~ s/<(\@|\??\$)/<#INTERPOLATE_FANCY_DEFANG#$1/gsi if defined $blosxom::title;
+      $blosxom::body =~ s/<(\@|\??\$)/<#INTERPOLATE_FANCY_DEFANG#$1/gsi if defined $blosxom::body;
     }
 
     my $template = shift;
 
     # Backward Compatibility with core Blosxom style interpolation
     unless ($parsing_story)
-       {$template =~ s#(?<!<)(?<!<\?)(?<!<\?!)(\$\w+(?:::)?\w*)#<$1 />#gs; };
+       {$template =~ s#(?<!<)(?<!<\?)(?<!<\?!)(\$\w+(?:::\w+)*)#<$1 />#gs; };
 
     #
     # Conditional inclusion
@@ -128,14 +134,14 @@ sub interpolate {
     # Variable expansion (unconditional, recursive)
     #
     # e.g. <$var />
-    while( $template =~ s/<\$([a-zA-Z?]\w+(?:::)?\w*)\s+?\/>/"defined \$$1 ? \$$1 : undef"/gsee ) { }
+    while( $template =~ s/<\$([a-zA-Z?]\w+(?:::\w+)*)\s+?\/>/"defined \$$1 ? \$$1 : ''"/gsee ) { }
 
     #
     # Actions 
     #
     # e.g. <@plugin.subroutine arg1="a" output="no" />
     # e.g. <@plugin.subroutine encoding="Latin1" output="yes">pass content</@> 
-    $template =~ s#<\@(\w+?)\.(\w+?)\s+?(.+?)?(?:>(.*?)<\/\@\1\.\2>|\s+?\/>)#&interpolate_fancy::_action($1,$2,$3,$4)#gse;
+    $template =~ s#<\@((?:\w|::)+?)\.(\w+?)\s+?(.+?)?(?:>(.*?)<\/\@\1\.\2>|\s+?\/>)#&interpolate_fancy::_action($1,$2,$3,$4)#gse;
 
     # Unmangle mangled interpolation tags in story $title and $body
     # (by now in the template itself)
@@ -145,11 +151,15 @@ sub interpolate {
 
     return $template;
 
-  };  
 }
 
 sub _test {
   my($variable, $attr) = @_;
+  # If the variable is not defined, treat it as the empty string in
+  # comparisons below
+  if (!defined $variable) { 
+    $variable = '';
+  }
   my $attributes = interpolate_fancy::_attributes($attr);
 
   defined $attributes->{eq} and return $variable eq $attributes->{eq};
@@ -166,15 +176,25 @@ sub _action {
   my($plugin, $action, $attr, $content) = @_;
   my $result;
 
-  $content =~ s#<\@(\w+?)\.(\w+?)\s+?(.+?)?(?:>(.*?)<\/\@\1\.\2>|\s+?\/>)#&interpolate_fancy::_action($1,$2,$3,$4)#gse;
+  if (defined $content) {
+    $content =~ s#<\@((?:\w|::)+?)\.(\w+?)\s+?(.+?)?(?:>(.*?)<\/\@\1\.\2>|\s+?\/>)#&interpolate_fancy::_action($1,$2,$3,$4)#gse;
+  }
 
   my $attributes = interpolate_fancy::_attributes($attr);
   
   $blosxom::plugins{$plugin} > 0
     and $plugin->can($action) 
       and $result = $plugin->$action($attributes, $content);
-
-  return $attributes->{'output'} =~ /yes/i ? $result : undef;
+  # Optionally interpolate and/or output the result, if requested. 
+  if ($attributes->{'output'} =~ /yes/i) {
+    if ($attributes->{'interpolate'} =~ /yes/i) {
+      $result = interpolate_fancy::do_interpolate($result);
+    } 
+    return $result;
+  } else {
+    return undef;
+  }
 }
 
 sub _attributes {
@@ -303,6 +323,10 @@ Specify that results should be sent to the browser using the output="yes" attrib
 
 Otherwise, subroutines will still have their effect, but the results will be tossed out.
 
+Normally, the result from the subroutine is sent as-is, but you can set the interpolate="yes" attribute to let interpolate_fancy interpolate the results, as follows:
+
+  <@plugin.subroutine arg1="a" arg2="bee" output="yes" interpolate="yes"/>
+
 Content wrapped in the action call is sent as another argument to the subroutine:
 
   <@thePlugin.subroutine encoding="Latin1" output="yes">
@@ -341,6 +365,14 @@ sub foreshorten {
   return substr($content, 0, $attributes->{'length'}||$default_length);
 }
 
+# This action includes the template specified in the 'name' attribute
+
+sub includetemplate {
+  my($self, $attributes, $content) = @_;
+  $name = $attributes->{'name'};
+  return &$blosxom::template($blosxom::path_info, $name, $blosxom::flavour);
+}
+
 --
 
 Calling these individually in a Blosxom flavour template looks something like:
@@ -369,6 +401,11 @@ The following bit of text is only 20 characters in length and devoid of HTML:
 </@myplugin.strip_html>
 </@myplugin.foreshorten>
 
+The following includes the 'sidebar' template, while interpolating
+the contents of that file:
+
+<@myplugin.include name="sidebar" output="yes" interpolate="yes"/>
+
 =head1 INSTALLATION
 
 Drop the interpolate_fancy plug-in into your Blosxom plugins folder.
@@ -407,8 +444,17 @@ run your templates through the interpolate2fancy utility
 
 =head1 VERSION
 
+2007-09-27
+
+=head1 VERSION HISTORY
+
+2007-09-27 : enables more than one :: in variable names
+
 2007-09-13 : corrects the $recurse_into_story feature in XML flavours
 
+v20061114 : fixes from Matthijs Kooijman (including properly support for nested
+conditions)
+
 =head1 AUTHOR
 
 Rael Dornfest  <rael@oreilly.com>, http://www.raelity.org/