[interchange-cvs] interchange - heins modified code/SystemTag/local.coretag

interchange-cvs at icdevgroup.org interchange-cvs at icdevgroup.org
Sat Apr 7 12:08:45 EDT 2007


User:      heins
Date:      2007-04-07 16:08:44 GMT
Added:     code/SystemTag local.coretag
Log:
* The local tag allows you to drop some code using scratch or values
  settings in a page without the possibility of affecting the overall
  operation of the site. It copies the keys you specify to a local store,
  runs the ITL, then restores them.

* Operates as such:

	[set foo]bar[/set]

	[local scratch="foo"]
		[set foo]nonbar[/set]
		foo=[scratch foo]
	[/local]

	[if scratch foo eq bar]
		local worked.
	[else]
		local did not work, kept at [scratch foo].
	[/else]
	[/if]

* Will not handle code references, but does individual keys to preserve
  them in other places

* Here is a test I did with it:

zero=[calc] %$Scratch = (); %$Values = (); delete $Session->{arbitrary};[/calc]

[set foo]foome[/set]
[set bar]barme[/set]
[value name=me hide=1 set=nothing]
[value name=mi hide=1 set=unrelated]
[calc]
	$Session->{arbitrary} = [ qw/ 1 2 3 4 /, sub { return 1 }, { foo => bar } ];
	return;
[/calc]

initial scratch=[calc]uneval($Scratch)[/calc]<br><br>
initial values=[calc]uneval($Values)[/calc]<br><br>
initial arbitrary=[calc]uneval($Session->{arbitrary})[/calc]
<hr>

[local scratch="foo bar buz" values="me mi mo" extra=arbitrary]

	[calc]
		# Set up test
		$Scratch->{foo} = 'barit';
		$Scratch->{bar} = 'fooit';
		$Scratch->{buz} = 'nevairbe';

		$Values->{me} = 'my';
		$Values->{mi} = 'mo';
		$Values->{mo} = 'mu';

		$Session->{arbitrary} = '';
	[/calc]
in local scratch=[calc]uneval($Scratch)[/calc]<br><br>
in local values=[calc]uneval($Values)[/calc]<br><br>
in local arbitrary=[calc]uneval($Session->{arbitrary})[/calc]

[/local]
<hr>
after local scratch=[calc]uneval($Scratch)[/calc]<br><br>
after local values=[calc]uneval($Values)[/calc]<br><br>
after local arbitrary=[calc]uneval($Session->{arbitrary})[/calc]

Revision  Changes    Path
1.1                  interchange/code/SystemTag/local.coretag


rev 1.1, prev_rev 1.0
Index: local.coretag
===================================================================
UserTag local Order scratch
UserTag local attrAlias scratches scratch
UserTag local attrAlias value values
UserTag local posNumber 1
UserTag local hasEndTag
UserTag local addAttr
UserTag local Description Tag to localize scratch and/or values for block
UserTag local Routine <<EOR
sub {
	my ($scratch, $opt, $body) = @_;

	use Storable qw/ dclone /;
	$Storable::forgive_me = 1;

	## It may seem simpler just to clone the top-level reference and
	## be done with it, but we are going through all these gyrations
	## to prevent the problem of overwriting code, which is not
	## preserved with a cloning operation.
	##
	## Obviously (or maybe not) if you pass a top-level array which
	## happens to contain a code reference, you are going to lose it.
	## But code references which are in non-localized hash keys will
	## survive.

	my %delete_top;
	my %delete;
	my %settings;

	# Perhaps {extra} is a bad option, but it has to be something. We
	# don't have the _ intro for a key, alas. Doubt it will often be
    # used, but discounts could be localized, I suppose.

	my @extra = split /[,\s\0]+/, $opt->{extra};

	for my $top (qw/ values scratch /, @extra) {

		exists $Vend::Session->{$top}
			or do {
				$delete_top{$top} = 1;
				next;
			};

		my $v = $Vend::Session->{$top};

		unless (ref($v) eq 'HASH') {
			if(! ref $v) {
				$settings{$top} = $v;
			}
			else {
				$settings{$top} = dclone($v);
			}
			next;
		}

		my @values = Text::ParseWords::shellwords($opt->{$top});

		for(@values) {
			if( ! exists $v->{$_}) {
				$delete{$top}{$_} = 1;
			}
			elsif(! ref $v->{$_}) {
				$settings{$top}{$_} = $v->{$_};
			}
			else {
				$settings{$top}{$_} = dclone($v->{$_});
			}
		}
	}

	my $result = interpolate_html($body);

	for my $top (qw/ values scratch /, @extra) {
		if(my $d = $delete_top{$top}) {
			delete $Vend::Session->{$top};
			next;
		}

		unless (ref($settings{$top}) eq 'HASH') {
			$Vend::Session->{$top} = $settings{$top};
			next;
		}

		my $s = $settings{$top};
		my $d = $delete{$top};
		my $v = $Vend::Session->{$top};

		for(keys %$d) {
			delete $v->{$_};
		}

		for(keys %$s) {
			$v->{$_} = $settings{$top}{$_};
		}
	}

	return $result;

}
EOR

UserTag local Documentation <<EOT
=head1 NAME

local -- localize scratch, values, etc. for code block.

=head1 SYNOPSIS

	[set foo]bar[/set]

	[local scratch="foo"]
		[set foo]nonbar[/set]
		foo=[scratch foo]
	[/local]

	[if scratch foo eq bar]
		local worked.
	[else]
		local did not work, kept at [scratch foo].
	[/else]
	[/if]

=head1 DESCRIPTION

The local tag allows you to drop some code using scratch or values settings
in a page without the possibility of affecting the overall operation of the
site.

EOT









More information about the interchange-cvs mailing list