X-Git-Url: https://git.p6c8.net/devedit.git/blobdiff_plain/03d83644ce2d958fe3e0466fa272c67f0566f4ab..633e5feee661afa985e87a66b524650ed1eae55a:/modules/Template.pm?ds=sidebyside diff --git a/modules/Template.pm b/modules/Template.pm index e3fbb98..ea2a9cc 100644 --- a/modules/Template.pm +++ b/modules/Template.pm @@ -1,12 +1,12 @@ package Template; # -# Template (Version 1.2a) +# Template (Version 1.5) # # Klasse zum Parsen von Templates # -# Autor: Patrick Canterino -# Letzte Aenderung: 12.9.2003 +# Autor: Patrick Canterino +# Letzte Aenderung: 4.5.2005 # use strict; @@ -24,7 +24,7 @@ use Carp qw(croak); sub new { my $class = shift; - my $self = {template => ''}; + my $self = {file => '', template => ''}; return bless($self,$class); } @@ -73,23 +73,29 @@ sub add_text($) # read_file() # -# Einlesen einer Vorlagendatei -# (Inhalt wird an bereits vorhandenen Text angehaengt) +# Einlesen einer Vorlagendatei und {INCLUDE}-Anweisungen ggf. verarbeiten +# (Text wird an bereits vorhandenen Text angehaengt) # -# Parameter: Datei zum Einlesen +# Parameter: 1. Datei zum Einlesen +# 2. Status-Code (Boolean): +# true => {INCLUDE}-Anweisungen nicht verarbeiten +# false => {INCLUDE}-Anweisungen verarbeiten (Standard) # # Rueckgabe: -nichts- (Template-Objekt wird modifiziert) -sub read_file($) +sub read_file($;$) { - my ($self,$tfile) = @_; + my ($self,$file,$not_include) = @_; local *FILE; - open(FILE,"<$tfile") or croak "Open $tfile: $!"; - read(FILE, my $content, -s $tfile); - close(FILE) or croak "Closing $tfile: $!"; + $self->{'file'} = $file; + + open(FILE,'<'.$file) or croak "Open $file: $!"; + read(FILE, my $content, -s $file); + close(FILE) or croak "Closing $file: $!"; $self->add_text($content); + $self->parse_includes unless($not_include); } # fillin() @@ -106,7 +112,7 @@ sub fillin($$) my ($self,$var,$text) = @_; $var = quotemeta($var); - $text = "" unless defined $text; # Um Fehler zu vermeiden + $text = '' unless defined $text; # Um Fehler zu vermeiden my $template = $self->get_template; $template =~ s/\{$var\}/$text/g; @@ -121,7 +127,7 @@ sub fillin($$) # Parameter: 1. Variable zum Ersetzen # 2. Array-Referenz, durch die die Variable ersetzt werden soll # 3. Zeichenkette, mit der das Array verbunden werden soll -# (Standard: "") +# (Standard: '') # # Rueckgabe: -nichts- (Template-Objekt wird modifiziert) @@ -133,40 +139,74 @@ sub fillin_array($$;$) $self->fillin($var,join($glue,@$array)); } +# to_file() +# +# Template in Datei schreiben +# +# Parameter: Datei-Handle +# +# Rueckgabe: Status-Code (Boolean) + +sub to_file($) +{ + my ($self,$handle) = @_; + return print $handle $self->get_template; +} + # parse_if_block() # # IF-Bloecke verarbeiten # # Parameter: 1. Name des IF-Blocks (das, was nach dem IF steht) -# 2. Statuscode (true => Inhalt anzeigen -# false => Inhalt nicht anzeigen +# 2. Status-Code (true => Inhalt anzeigen +# false => Inhalt nicht anzeigen +# 3. true => Verneinten Block nicht parsen +# false => Verneinten Block parsen (Standard) # # Rueckgabe: -nichts- (Template-Objekt wird modifiziert) -sub parse_if_block($$) +sub parse_if_block($$;$) { - my ($self,$name,$state) = @_; - my $template = $self->get_template; + my ($self,$name,$state,$no_negate) = @_; + my $template = $self->get_template; + + my $count = 0; - while(index($template,"{IF ".$name."}") >= 0) + while(index($template,'{IF '.$name.'}') >= 0) { # Das alles hier ist nicht wirklich elegant geloest... # ... aber solange es funktioniert... ;-) - my $start = index($template,"{IF ".$name."}"); + $count++; + + my $start = index($template,'{IF '.$name.'}'); my $tpl_tmp = substr($template,$start); my @splitted = split(/\{ENDIF\}/,$tpl_tmp); - my $block = ""; # Kompletter bedingter Block + # Wenn sich am Ende der Zeichenkette {ENDIF} befinden, werden diese + # von split() ignoriert, was zu einem Verschachtelungsfehler fuehrt + # Die fehlenden leeren Zeichenketten muessen von Hand eingefuegt werden + + my $x = 1; + + while(substr($tpl_tmp,-7*$x,7) eq '{ENDIF}') + { + push(@splitted,''); + $x++; + } + + my $block = ''; # Kompletter bedingter Block my $ifs = 0; # IF-Zaehler (wird fuer jedes IF erhoeht und fuer jedes ENDIF erniedrigt) # {IF} for(my $x=0;$x<@splitted;$x++) { - $ifs += substr_count($splitted[$x],"{IF"); # Zum Zaehler jedes Vorkommen von IF hinzuzaehlen - $ifs--; # Zaehler um 1 erniedrigen - $block .= $splitted[$x]."{ENDIF}"; # Daten zum Block hinzufuegen + croak 'Nesting error found while parsing IF block "'.$name.'" nr. '.$count.' in template file "'.$self->{'file'}.'"' if($x == $#splitted); + + $ifs += substr_count($splitted[$x],'{IF '); # Zum Zaehler jedes Vorkommen von IF hinzuzaehlen + $ifs--; # Zaehler um 1 erniedrigen + $block .= $splitted[$x].'{ENDIF}'; # Daten zum Block hinzufuegen if($ifs == 0) { @@ -180,15 +220,15 @@ sub parse_if_block($$) # {ELSE} - my $else_block = ""; # Alles ab {ELSE} + my $else_block = ''; # Alles ab {ELSE} $ifs = 0; # IF-Zaehler @splitted = split(/\{ELSE\}/,$if_block); for(my $x=0;$x<@splitted;$x++) { - $ifs += substr_count($splitted[$x],"{IF"); # Zum Zaehler jedes Vorkommen von IF hinzuzaehlen - $ifs -= substr_count($splitted[$x],"{ENDIF}"); # Vom Zaehler jedes Vorkommen von ENDIF abziehen + $ifs += substr_count($splitted[$x],'{IF '); # Zum Zaehler jedes Vorkommen von IF hinzuzaehlen + $ifs -= substr_count($splitted[$x],'{ENDIF}'); # Vom Zaehler jedes Vorkommen von ENDIF abziehen if($ifs == 0) { @@ -198,13 +238,13 @@ sub parse_if_block($$) for(my $y=$x+1;$y<@splitted;$y++) { - $else_block .= "{ELSE}".$splitted[$y]; + $else_block .= '{ELSE}'.$splitted[$y]; } if($else_block) { $if_block = substr($if_block,0,length($if_block)-length($else_block)); - $else_block = (length($else_block) > 6) ? substr($else_block,6) : ""; # Ansonsten gibt es Fehler + $else_block = (length($else_block) > 6) ? substr($else_block,6) : ''; # Ansonsten gibt es Fehler } last; @@ -219,6 +259,13 @@ sub parse_if_block($$) } $self->set_template($template); + + # Evtl. verneinte Form parsen + + unless($no_negate) + { + $self->parse_if_block('!'.$name,not($state),1); + } } # parse_condtag() @@ -226,8 +273,8 @@ sub parse_if_block($$) # Bedingungstags in einem Vorlagentext verarbeiten # # Parameter: 1. Tagname -# 2. Statuscode (true => Tag-Inhalt anzeigen -# false => Tag-Inhalt nicht anzeigen +# 2. Status-Code (true => Tag-Inhalt anzeigen +# false => Tag-Inhalt nicht anzeigen # # Rueckgabe: -nichts- (Template-Objekt wird modifiziert) @@ -237,19 +284,49 @@ sub parse_condtag($$) my $template = $self->get_template; - while(index($template,"<$condtag>") >= 0) + while(index($template,'<'.$condtag.'>') >= 0) { - my $start = index($template,"<$condtag>"); # Beginn des Blocks - my $end = index($template,"")+length($condtag)+3; # Ende des Blocks + my $start = index($template,'<'.$condtag.'>'); # Beginn des Blocks + my $end = index($template,'')+length($condtag)+3; # Ende des Blocks - my $extract = substr($template,$start,$end-$start); # Kompletten Bedingungsblock extrahieren... + my $extract = substr($template,$start,$end-$start); # Kompletten Bedingungsblock extrahieren... - my $replacement = ($state) ? substr($extract,length($condtag)+2,0-length($condtag)-3) : ""; + my $replacement = ($state) ? substr($extract,length($condtag)+2,0-length($condtag)-3) : ''; $extract = quotemeta($extract); - $template =~ s/$extract/$replacement/g; # Block durch neue Daten ersetzen + $template =~ s/$extract/$replacement/g; # Block durch neue Daten ersetzen + } + $self->set_template($template); +} + +# parse_includes() +# +# {INCLUDE}-Anweisungen verarbeiten +# +# Parameter: -nichts- +# +# Rueckgabe: -nichts- (Template-Objekt wird modifiziert) + +sub parse_includes +{ + my $self = shift; + my $template = $self->get_template; + + while($template =~ /(\{INCLUDE (\S+?)\})/g) + { + my ($directive,$file) = ($1,$2); + my $qm_directive = quotemeta($directive); + + if(-f $file) + { + my $inc = new Template; + $inc->read_file($file); + + $template =~ s/$qm_directive/$inc->get_template/eg; + } } + $self->set_template($template); } @@ -283,25 +360,10 @@ sub substr_count($$) # Alias-Funktionen # ================== -sub addtext($) -{ - shift->add_text(shift); -} - -sub as_string -{ - return shift->get_template; -} - -sub condtag($$) -{ - shift->parse_condtag(@_); -} - -sub readin($) -{ - shift->read_file(shift); -} +*addtext = \&add_text; +*as_string = \&get_template; +*condtag = \&parse_condtag; +*readin = \&read_file; # it's true, baby ;-)