From eeb750d0481d0cb8e27a7ccef3d39254306e7ce4 Mon Sep 17 00:00:00 2001 From: Gavin Carr Date: Wed, 5 Sep 2007 07:04:12 +0000 Subject: [PATCH] Update interpolate_fancy to v20061114 with fixes from Matthijs Kooijman. --- general/interpolate_fancy | 138 +++++++++++++++++++++++++++++--------- 1 file changed, 108 insertions(+), 30 deletions(-) diff --git a/general/interpolate_fancy b/general/interpolate_fancy index 1a7f21c..6a41ca0 100644 --- a/general/interpolate_fancy +++ b/general/interpolate_fancy @@ -1,6 +1,7 @@ # Blosxom Plugin: interpolate_fancy -# Author(s): Rael Dornfest -# Version: 2003-09-09:12:10 +# Author: Rael Dornfest , +# Modified by: Matthijs Kooijman +# Version: 2006-01-14 # Documentation: See the bottom of this file or type: # perldoc interpolate_fancy @@ -14,7 +15,7 @@ package interpolate_fancy; # there's a chance of some tomfoolery, exposing variables and calling # actions/subroutines you might not want called. # 0 = No (default), 1 = Yes -my $recurse_into_story = 0; +our $recurse_into_story = 0; # -------------------------------- @@ -22,6 +23,74 @@ sub start { 1; } + +# (Recursively) resolve conditinal includes .... +# Expects two arguments: The (part of the) template we are expanding and +# wether or not this part will be displayed. When this last argument is false, +# this part of the template will not be displayed, but is still parsed to +# properly resolve nested conditions. +# +# This will resolve and substitute all conditionals on the "current level". +# This effectively means, the routine will search for and resolve all tags it +# finds (with proper nesting), until it finds a closing tag () for which +# it has not seen the opening tag, or there are no more opening tags in the +# file. +# +# This function will return the template with all conditionals on the current +# level resolved. This will guarantee that if there are any opening or closing +# tags left in the template, the first one will be a closing tag (which can +# then be resolved in the upper level). +sub _resolve_nested { + my $template = shift; + my $display = shift; + + while (1) { + if ($template !~ /(.*?)<\?(\!?\$\w+(?:::)?\w*)(?:\s+?(.+?))?>(.*)/s) { + return $template; # No open tags, normal text + } + + my $head = $1; + my $var = $2; + my $attr = $3; + my $tail = $4; + + if ($head =~ /<\/\?>/s) { + return $template; # There is a closing tag before the first open tag, + # we're done. + } + + $displayitem = $display; + if ($displayitem) { # Don't care about these tests if we're not displayed anyway. + my $negated = ($var =~ s/^\!//); # Remove negation mark + if ($negated || !$attr) { + if ($attr) { + warn(": Negated expression can't have attributes, ignoring them."); + } + $displayitem = eval("defined $var"); + if ($negated) { $displayitem = !$displayitem; } + } else { + $displayitem = _test(eval($var), $attr); + } + } + + + $tail = _resolve_nested($tail, $displayitem); + + if ($tail !~ /<\/\?>/s) { # Is there no closing tag? + warn("Invalid nesting: missing closing tag."); + } + if ($displayitem) + { + $tail =~ s/<\/\?>//s; # Remove the closing tag + } else { + $tail =~ s/.*?<\/\?>//s; # Remove up to the closing tag + } + $template = $head . $tail; + } + return $template; +} + + sub interpolate { return sub { @@ -39,24 +108,21 @@ sub interpolate { # Backward Compatibility with core Blosxom style interpolation $template =~ s#(?#gs; - # Defined - # e.g. display if defined - $template =~ s#<\?(\$\w+(?:::)?\w*)>(.*?)<\/\?>#"defined $1 ? \$2 : undef"#gsee; - - # Undefined - # e.g. display if not defined - $template =~ s#<\?!(\$\w+(?:::)?\w*)>(.*?)<\/\?>#"!defined $1 ? \$2 : undef"#gsee; + # + # Conditional inclusion + # + # e.g. stuff + $template = interpolate_fancy::_resolve_nested($template, 1); - # Tests - # eq (eq), ne (ne), lt (<), gt (>), like (=~), unlike (!~) - # e.g. display if $var less than 123 - $template =~ s#<\?(\$\w+(?:::)?\w*)\s+?(.+?)>(.*?)<\/\?>#"interpolate_fancy::_test(qq{$1}, q{$2}, q{$3})"#gsee; - - # Unconditional, Recursive + # + # Variable expansion + # # e.g. <$var /> while( $template =~ s/<\$([a-zA-Z?]\w+(?:::)?\w*)\s+?\/>/"defined \$$1 ? \$$1 : undef"/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; @@ -73,20 +139,17 @@ sub interpolate { } sub _test { - my($variable, $attr, $content) = @_; - - my $result; - + my($variable, $attr) = @_; my $attributes = interpolate_fancy::_attributes($attr); - defined $attributes->{eq} and return $variable eq $attributes->{eq} ? $content : undef; - defined $attributes->{ne} and return $variable ne $attributes->{ne} ? $content : undef; - defined $attributes->{gt} and return $variable > $attributes->{gt} ? $content : undef; - defined $attributes->{lt} and return $variable < $attributes->{lt} ? $content : undef; - defined $attributes->{like} and return $variable =~ /$attributes->{like}/ ? $content : undef; - defined $attributes->{unlike} and return $variable !~ /$attributes->{unlike}/ ? $content : undef; + defined $attributes->{eq} and return $variable eq $attributes->{eq}; + defined $attributes->{ne} and return $variable ne $attributes->{ne}; + defined $attributes->{gt} and return $variable > $attributes->{gt}; + defined $attributes->{lt} and return $variable < $attributes->{lt}; + defined $attributes->{like} and return $variable =~ /$attributes->{like}/; + defined $attributes->{unlike} and return $variable !~ /$attributes->{unlike}/; - return undef; + return 0; } sub _action { @@ -133,7 +196,9 @@ conditionally or unconditionally: Perform actions (i.e. call plug-in subroutines) at any point in your page, whether to act on current content and return results or no. -=head2 Includes +=head2 Variable expansion + This syntax will expand to the value of the referenced variable and can be + used to include dynamic content in your pages. * Unconditionally and recursively @@ -153,6 +218,18 @@ whether to act on current content and return results or no. Limited by the $recurse_into_story configuration directive (see the CONFIGURATION below). +==head2 Conditional inclusion + These tags will each have a certain condition attached to them, depending on + what syntax is used exactly. All text between the opening and closing tags + will only be included in the final output of the page if the given condition + is true, it will be discarded otherwise. + + Note that as of 2006-01-11 conditional tags can be nested, which effectively + allows you to specify the logical and of two (or more) conditions. There is + no way yet to specify the logical or, though. If you're using nested + conditions and they won't work properly, check your error log, since the + plugin puts warnings about incorrect nestings there. + * The template variable has a value (i.e. is defined) e.g. include a hyperlink to the story's path if it has a path (i.e. @@ -332,15 +409,16 @@ requiring no template rewriting on your part. If you've been using the interpolate_conditional plugin, the conditional bits won't be respected by default. You should run your templates through the interpolate2fancy utility -[http://blosxom.sourceforge.net/downloads/utilities/interpolate2fancy.py]. +[http://www.blosxom.com/downloads/utilities/interpolate2fancy.py]. =head1 VERSION -2003-09-09:12:10 +2006-01-11 =head1 AUTHOR Rael Dornfest , http://www.raelity.org/ +Modified by Matthijs Kooijman , http://katherina.student.utwente.nl/~matthijs/blog =head1 SEE ALSO -- 2.30.2