]> git.p6c8.net - devedit.git/blob - modules/Template.pm
Copying and renaming of files is back again!
[devedit.git] / modules / Template.pm
1 package Template;
2
3 #
4 # Template (Version 1.2a)
5 #
6 # Klasse zum Parsen von Templates
7 #
8 # Autor: Patrick Canterino <patshaping@gmx.net>
9 # Letzte Aenderung: 12.9.2003
10 #
11
12 use strict;
13
14 use Carp qw(croak);
15
16 # new()
17 #
18 # Konstruktor
19 #
20 # Parameter: -keine-
21 #
22 # Rueckgabe: Template-Objekt
23
24 sub new
25 {
26 my $class = shift;
27 my $self = {template => ''};
28 return bless($self,$class);
29 }
30
31 # get_template()
32 #
33 # Kompletten Vorlagentext zurueckgeben
34 #
35 # Parameter: -keine-
36 #
37 # Rueckgabe: Kompletter Vorlagentext (String)
38
39 sub get_template
40 {
41 return shift->{'template'};
42 }
43
44 # set_template()
45 #
46 # Kompletten Vorlagentext aendern
47 #
48 # Parameter: Vorlagentext
49 #
50 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
51
52 sub set_template($)
53 {
54 # Geht nur so...
55
56 my ($self,$template) = @_;
57 $self->{'template'} = $template;
58 }
59
60 # add_text()
61 #
62 # Vorlagentext ans Template-Objekt anhaengen
63 #
64 # Parameter: Vorlagentext
65 #
66 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
67
68 sub add_text($)
69 {
70 my ($self,$text) = @_;
71 $self->set_template($self->get_template.$text);
72 }
73
74 # read_file()
75 #
76 # Einlesen einer Vorlagendatei
77 # (Inhalt wird an bereits vorhandenen Text angehaengt)
78 #
79 # Parameter: Datei zum Einlesen
80 #
81 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
82
83 sub read_file($)
84 {
85 my ($self,$tfile) = @_;
86 local *FILE;
87
88 open(FILE,"<$tfile") or croak "Open $tfile: $!";
89 read(FILE, my $content, -s $tfile);
90 close(FILE) or croak "Closing $tfile: $!";
91
92 $self->add_text($content);
93 }
94
95 # fillin()
96 #
97 # Variablen durch Text ersetzen
98 #
99 # Parameter: 1. Variable zum Ersetzen
100 # 2. Text, durch den die Variable ersetzt werden soll
101 #
102 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
103
104 sub fillin($$)
105 {
106 my ($self,$var,$text) = @_;
107
108 $var = quotemeta($var);
109 $text = "" unless defined $text; # Um Fehler zu vermeiden
110
111 my $template = $self->get_template;
112 $template =~ s/\{$var\}/$text/g;
113
114 $self->set_template($template);
115 }
116
117 # fillin_array()
118 #
119 # Variable durch Array ersetzen
120 #
121 # Parameter: 1. Variable zum Ersetzen
122 # 2. Array-Referenz, durch die die Variable ersetzt werden soll
123 # 3. Zeichenkette, mit der das Array verbunden werden soll
124 # (Standard: "")
125 #
126 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
127
128 sub fillin_array($$;$)
129 {
130 my ($self,$var,$array,$glue) = @_;
131 $glue = '' unless defined $glue;
132
133 $self->fillin($var,join($glue,@$array));
134 }
135
136 # parse_if_block()
137 #
138 # IF-Bloecke verarbeiten
139 #
140 # Parameter: 1. Name des IF-Blocks (das, was nach dem IF steht)
141 # 2. Statuscode (true => Inhalt anzeigen
142 # false => Inhalt nicht anzeigen
143 #
144 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
145
146 sub parse_if_block($$)
147 {
148 my ($self,$name,$state) = @_;
149 my $template = $self->get_template;
150
151 while(index($template,"{IF ".$name."}") >= 0)
152 {
153 # Das alles hier ist nicht wirklich elegant geloest...
154 # ... aber solange es funktioniert... ;-)
155
156 my $start = index($template,"{IF ".$name."}");
157 my $tpl_tmp = substr($template,$start);
158 my @splitted = split(/\{ENDIF\}/,$tpl_tmp);
159
160 my $block = ""; # Kompletter bedingter Block
161 my $ifs = 0; # IF-Zaehler (wird fuer jedes IF erhoeht und fuer jedes ENDIF erniedrigt)
162
163 # {IF}
164
165 for(my $x=0;$x<@splitted;$x++)
166 {
167 $ifs += substr_count($splitted[$x],"{IF"); # Zum Zaehler jedes Vorkommen von IF hinzuzaehlen
168 $ifs--; # Zaehler um 1 erniedrigen
169 $block .= $splitted[$x]."{ENDIF}"; # Daten zum Block hinzufuegen
170
171 if($ifs == 0)
172 {
173 # Zaehler wieder 0, also haben wir das Ende des IF-Blocks gefunden :-))
174
175 last;
176 }
177 }
178
179 my $if_block = substr($block,length($name)+5,-7); # Alles zwischen {IF} und {ENDIF}
180
181 # {ELSE}
182
183 my $else_block = ""; # Alles ab {ELSE}
184 $ifs = 0; # IF-Zaehler
185
186 @splitted = split(/\{ELSE\}/,$if_block);
187
188 for(my $x=0;$x<@splitted;$x++)
189 {
190 $ifs += substr_count($splitted[$x],"{IF"); # Zum Zaehler jedes Vorkommen von IF hinzuzaehlen
191 $ifs -= substr_count($splitted[$x],"{ENDIF}"); # Vom Zaehler jedes Vorkommen von ENDIF abziehen
192
193 if($ifs == 0)
194 {
195 # Zaehler 0, also haben wir das Ende des IF-Abschnitts gefunden
196
197 # Aus dem Rest den ELSE-Block zusammenbauen
198
199 for(my $y=$x+1;$y<@splitted;$y++)
200 {
201 $else_block .= "{ELSE}".$splitted[$y];
202 }
203
204 if($else_block)
205 {
206 $if_block = substr($if_block,0,length($if_block)-length($else_block));
207 $else_block = (length($else_block) > 6) ? substr($else_block,6) : ""; # Ansonsten gibt es Fehler
208 }
209
210 last;
211 }
212 }
213
214 my $replacement = ($state) ? $if_block : $else_block;
215
216 my $qmblock = quotemeta($block);
217
218 $template =~ s/$qmblock/$replacement/;
219 }
220
221 $self->set_template($template);
222 }
223
224 # parse_condtag()
225 #
226 # Bedingungstags in einem Vorlagentext verarbeiten
227 #
228 # Parameter: 1. Tagname
229 # 2. Statuscode (true => Tag-Inhalt anzeigen
230 # false => Tag-Inhalt nicht anzeigen
231 #
232 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
233
234 sub parse_condtag($$)
235 {
236 my ($self,$condtag,$state) = @_;
237
238 my $template = $self->get_template;
239
240 while(index($template,"<$condtag>") >= 0)
241 {
242 my $start = index($template,"<$condtag>"); # Beginn des Blocks
243 my $end = index($template,"</$condtag>")+length($condtag)+3; # Ende des Blocks
244
245 my $extract = substr($template,$start,$end-$start); # Kompletten Bedingungsblock extrahieren...
246
247 my $replacement = ($state) ? substr($extract,length($condtag)+2,0-length($condtag)-3) : "";
248
249 $extract = quotemeta($extract);
250
251 $template =~ s/$extract/$replacement/g; # Block durch neue Daten ersetzen
252 }
253 $self->set_template($template);
254 }
255
256 # ==================
257 # Private Funktion
258 # ==================
259
260 # substr_count()
261 #
262 # Zaehlt, wie oft ein String in einem String vorkommt
263 # (Emulation der PHP-Funktion substr_count())
264 #
265 # Parameter: 1. Zu durchsuchender String
266 # 2. Zu suchender String
267 #
268 # Rueckgabe: Anzahl der Vorkommnisse (Integer)
269
270 sub substr_count($$)
271 {
272 my ($haystack,$needle) = @_;
273 my $qmneedle = quotemeta($needle);
274
275 my $count = 0;
276
277 $count++ while($haystack =~ /$qmneedle/g);
278
279 return $count;
280 }
281
282 # ==================
283 # Alias-Funktionen
284 # ==================
285
286 sub addtext($)
287 {
288 shift->add_text(shift);
289 }
290
291 sub as_string
292 {
293 return shift->get_template;
294 }
295
296 sub condtag($$)
297 {
298 shift->parse_condtag(@_);
299 }
300
301 sub readin($)
302 {
303 shift->read_file(shift);
304 }
305
306 # it's true, baby ;-)
307
308 1;
309
310 #
311 ### Ende ###

patrick-canterino.de