package Template::Parser;
use strict;
use Exporter;
use Futils qw( :all );
$Template::Parser::VERSION = 4.03_6; # 9/19/02, 8:33 pm
@Template::Parser::ISA = qw( Futils Exporter );
@Template::Parser::EXPORT = @Futils::EXPORT;
@Template::Parser::EXPORT_OK = @Futils::EXPORT_OK;
%Template::Parser::EXPORT_TAGS = %Futils::EXPORT_TAGS;
=pod
AUTHOR
Tommy Butler <tommy @ atrixnet.com>
phone: (817)-468-7716
6711 Forest Park Dr
Arlington, TX
76001-8403
COPYRIGHT Tommy Butler. All rights reserved
LISCENCE This software is free, use/distribute under the GNU GPL.
BUGS TO Tommy Butler <perlmod @ atrixnet.com>
HISTORY
4.03_6
9/19/02, 8:33 pm
method 'delete_token' now takes a list, and returns a list of the
values for each token deleted, instead of simply returning a value of
1 as it has in previous versions.
=cut
# --------------------------------------------------------
# Constructor
# --------------------------------------------------------
sub new {
# get this namespace, arguments
my($this) = {};
# bless object ref into the class' namespace
bless($this, shift(@_));
# set up class attributes
my($in) = $this->coerce_array(@_);
$this->{'name'} = __PACKAGE__;
$this->{'config'} = $in->{'config'}||{};
# verify object attributes
$this->verify_attributes();
# initialize the object
$this->init();
# return object reference
return($this);
}
# --------------------------------------------------------
# Template::Parser::verify_attributes()
# --------------------------------------------------------
sub verify_attributes {
my($this) = shift(@_);
=pod
this is here in case there comes a
time that Template::Parser has any
required arguments for its new()
object method.
=cut
return(1);
}
# --------------------------------------------------------
# Template::Parser::init()
# --------------------------------------------------------
sub init {
my($this) = shift(@_);
# tag syntax used to deliniate embedded
# tokens within strings or files passed
# to Template::Parser::parse()
my($open_embed_tag) = $this->
{'config'}
{'open embed tag'} || q[<?=];
my($close_embed_tag) = $this->
{'config'}
{'close embed tag'} || q[?>];
my($open_token_tag) = $this->
{'config'}
{'open token tag'} || q[%%%];
my($close_token_tag) = $this->
{'config'}
{'close token tag'} || q[%%%];
# regular expression used to parse embedded
# tokens within user-defined template files
$this->{'tokenRE'} = qr/(?sx)
\Q$open_token_tag\E
(.*?)
\Q$close_token_tag\E/;
# regular expression used to parse embedded
# tokens within user-defined template files
$this->{'embedRE'} = qr/(?sx)
\Q$open_embed_tag\E
(.*?)
\Q$close_embed_tag\E/;
$this->{'embedEV'} = qr/(?<!my\()(?:\${1,2})([^ ]*?)(?:->|\{)/;
# create a refernced hash table to store
# tokenized data objects
$this->{'objects'} = {};
$this->set_token( 'Parser' => $this );
return(1);
}
# --------------------------------------------------------
# Template::Parser::parse()
# --------------------------------------------------------
sub parse {
my($this) = shift(@_);
my($string) = shift || undef;
return('') if (not defined($string));
{
local($^W)=0;
$string =~ s/$this->{'tokenRE'}/$this->_token_eval($1)/ge;
$string =~ s/$this->{'embedRE'}/$this->_embed_eval($1)/ge;
}
return($string);
}
# --------------------------------------------------------
# Template::Parser::parse_file()
# --------------------------------------------------------
sub parse_file {
my($this) = shift(@_);
return('') if (!defined($_[0]));
return( $this->parse($this->load_file($_[0])) );
}
# --------------------------------------------------------
# Template::Parser::_embed_eval()
# --------------------------------------------------------
sub _embed_eval {
my($this) = shift(@_); my($cmd) = $_[0];
$cmd =~ s/$this->{'embedEV'}/$this->_wrap_embed($1)/ge;
$cmd =~ s/\!Parser/\$this/g; &{ sub { CORE::eval($cmd); } }();
}
# --------------------------------------------------------
# Template::Parser::_embed_eval()
# --------------------------------------------------------
sub _token_eval {
my($this) = shift(@_);
my($tmp) = $_[0]; $tmp =~ s/^(.*?)$/$this->_wrap_token($1)/e;
undef($@); $tmp = CORE::eval( $tmp ); $@ || $tmp;
}
# --------------------------------------------------------
# Template::Parser::_wrap_embed()
# --------------------------------------------------------
sub _wrap_embed { q[$this->{'objects'}].q[{'].$_[1].q['}]; }
# --------------------------------------------------------
# Template::Parser::_wrap_token()
# --------------------------------------------------------
sub _wrap_token { q[$this->{'tokens'}{'].$_[1].q['}]; }
# --------------------------------------------------------
# Template::Parser::set_object()
# --------------------------------------------------------
sub set_object {
my($this) = shift(@_);
my($in) = $this->coerce_array(@_);
my($name) = $in->{'name'};
return(0)
unless
(
defined($in->{'name'})
and
defined($in->{'value'})
);
$in->{'value'} ||= '';
$in->{'name'} ||= '';
if (ref($in->{'value'}) eq 'HASH') {
$this->
{'objects'}->
{ $in->{'name'} } = $in->{'value'};
if ($in->{'cc tokens'}) {
foreach (keys(%{ $in->{'value'} })) {
$this->
set_token
(
'name' => $in->{'name'}.q[->].$_,
'value' => $in->{'value'}->{$_},
);
}
}
return($this->{'objects'}->{ $in->{'name'} });
}
elsif (defined($in->{'param'})) {
$this->
{'objects'}->
{ $in->{'name'} }->
{ $in->{'param'} } = $in->{'value'};
if ($in->{'cc tokens'}) {
$this->
set_token
(
'name' => $in->{'name'}.q[->].$in->{'param'},
'value' => $in->{'value'},
);
}
return($this->{'objects'}->{ $in->{'name'} }{ $in->{'param'} });
}
return(0);
}
# --------------------------------------------------------
# Template::Parser::make_token()
# --------------------------------------------------------
sub set_token {
my($this) = shift(@_);
my($name) = $_[0] || '';
my($value) = $_[1] || '';
my($in) = $this->coerce_array(@_);
return(0) if (scalar(@_) < 2);
$in->{'value'} ||= '';
$in->{'name'} ||= '';
if ($in->{'name'} and $in->{'value'}) {
$this->
{'tokens'}->
{ $in->{'name'} } = $in->{'value'};
return($this->{'tokens'}{ $in->{'name'} });
}
else {
$this->{'tokens'}{ $name } = $value;
return($this->{'tokens'}{ $name });
}
return(0);
}
# --------------------------------------------------------
# Template::Parser::get_object()
# --------------------------------------------------------
sub get_object {
my($this) = shift(@_);
my($in) = $this->coerce_array(@_);
$in->{'value'} ||= '';
$in->{'name'} ||= '';
return(0)
if
(
not defined($_[0])
);
return
(
$this->{'objects'}{ $in->{'name'} }{ $in->{'param'} }
)
if
(
defined
(
$this->{'objects'}{ $in->{'name'} }{ $in->{'param'} }
)
);
return
(
$this->{'objects'}{ $in->{'name'} }
)
if
(
defined
(
$this->{'objects'}{ $in->{'name'} }
)
);
return('');
}
# --------------------------------------------------------
# Template::Parser::get_token()
# --------------------------------------------------------
sub get_token {
my($this) = shift(@_);
my($in) = $this->coerce_array(@_);
return(0)
if
(
not defined($_[0])
);
return
(
$this->{'tokens'}{ $in->{'name'} }
)
if
(
defined
(
$this->{'tokens'}{ $in->{'name'} }
)
);
return('');
}
# --------------------------------------------------------
# Template::Parser::delete_object()
# --------------------------------------------------------
sub delete_object {
my($this) = shift(@_);
my($in) = $this->coerce_array(@_);
$in->{'name'} ||= return(0);
$in->{'param'} ||= '';
return(delete($this->{'objects'}{$in->{'name'}}{$in->{'param'}}))
if $in->{'param'};
return(delete($this->{'objects'}{ $in->{'name'} }));
}
# --------------------------------------------------------
# Template::Parser::delete_token()
# --------------------------------------------------------
sub delete_token {
my($this) = shift(@_);
my(@delete) = ();
foreach (@_) { push(@delete, delete($this->{'tokens'}{ $_ })); }
return(@delete);
}
# --------------------------------------------------------
# Template::Parser::load_object()
# --------------------------------------------------------
sub load_object {
my($this) = shift(@_);
my($dir) = shift(@_)||return({});
my($dir_hash) = {};
my(@files) = ();
# get list of files from Futils::list_dir()
@files =
$this->list_dir
(
$dir, '--files-only', '--no-fsdots'
);
# map the content of each file into
# a hash key-value element where the
# key name for each file is the name
# of the file
foreach (@files) {
my($keyname) = $_; $keyname =~ s/^(.*)\..*/$1/;
$dir_hash->{ $keyname } = $this->load_file( $dir . '/' . $_ );
}
# return a reference to the hash containing
# all the filenames and their contents
return($dir_hash);
}
# --------------------------------------------------------
# Template::Parser::flush_objects()
# --------------------------------------------------------
sub flush_objects { delete($$_[0]{'objects'}); 1 }
# --------------------------------------------------------
# Template::Parser::flush_tokens()
# --------------------------------------------------------
sub flush_tokens { delete($$_[0]{'tokens'}); 1 }
# --------------------------------------------------------
# Template::Parser::flush_all()
# --------------------------------------------------------
sub flush_all { delete($$_[0]{'objects'}); delete($$_[0]{'tokens'}); 1 }
# --------------------------------------------------------
# Template::Parser::DESTROY()
# --------------------------------------------------------
sub DESTROY { }
# --------------------------------------------------------
# End Template::Parser class, return true on import
# --------------------------------------------------------
1;