2 /* vim: set expandtab tabstop=4 shiftwidth=4: */
4 // Copyright (c) 2003 Laurent Bedubourg
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // Authors: Laurent Bedubourg <laurent.bedubourg@free.fr>
24 * Represents an xhtml entity.
26 * To obtain a fine granularity of code generation the Tag code generation
27 * process is divided into logical sub sequences.
29 * surround head // call surround attributes
30 * replace // call replace and skip head -> foo sequence
31 * || head // echo tag start (see disableHeadFoot())
32 * content // call content replace and skip cdata seq
33 * || cdata && child // echo tag content and generate children code
34 * foot // echo tag end (see disableHeadFoot())
35 * surround foot // call surround attributes
38 * Some attributes like 'omit' requires to disable the head / foot sequences
39 * whithout touching content sequences, the disableHeadFoot() method must be
43 * @author Laurent Bedubourg <laurent.bedubourg@free.fr>
48 * @var int $line The template line which produced this tag.
54 var $_name = "#cdata";
55 var $_attrs = array();
56 var $_children = array();
60 // template system properties
63 var $_replace_attributes = array();
64 var $_content_attributes = array();
65 var $_surround_attributes = array();
66 var $_head_foot_disabled = false;
75 * @param hashtable $attrs
76 * Tag xhtml attributes.
78 function PHPTAL_Tag(&$parser, $name, $attrs)
80 $this->_parser
=& $parser;
82 $this->_attrs
= $attrs;
85 function appendTemplateAttribute(&$hdlr)
87 switch ($hdlr->_phptal_type
)
90 $this->_replace_attributes
[] =& $hdlr;
93 $this->_content_attributes
[] =& $hdlr;
95 case _PHPTAL_SURROUND
:
96 $this->_surround_attributes
[] =& $hdlr;
99 return PEAR
::raiseError(
100 "PHPTAL internal error : bad attribute type : "
112 return $this->_name
== "#cdata";
115 function attributes()
117 return $this->_attrs
;
120 function setParent(&$node)
122 $this->_parent
=& $node;
125 function &getParent()
127 return $this->_parent
;
130 function addChild(&$node)
132 $node->setParent($this);
133 $this->_children
[] = &$node;
136 function setContent($str)
138 $this->_content
= $str;
141 function hasContent()
143 return (count($this->_content_attributes
) == 0
144 ||
count($this->_children
) == 0
145 ||
strlen($this->_content
) == 0);
148 function toString($tab="")
150 $buf = new StringBuffer();
151 $buf->appendln($tab, '+ node ', $this->name());
152 for ($i=0; $i < count($this->_children
); $i++
) {
153 $child =& $this->_children
[$i];
154 $buf->append($child->toString($tab . " "));
157 return $buf->toString();
160 function generateCode(&$g)
162 // if text node, just print the content and return
163 if ($this->_name
== "#cdata") {
164 $g->doPrintString($this->_content
);
168 if ($this->_name
== "#root") {
169 return $this->generateContent($g);
172 // if replace attributes exists, they will handle
173 // this tag rendering
174 if (count($this->_replace_attributes
) > 0) {
175 $err = $this->surroundHead($g);
176 if (PEAR
::isError($err)) { return $err; }
178 for ($i=0; $i<count($this->_replace_attributes
); $i++
) {
179 $h =& $this->_replace_attributes
[$i];
180 $err = $h->activate($g, $this);
181 if (PEAR
::isError($err)) { return $err; }
184 return $this->surroundFoot($g);
187 $err = $this->surroundHead($g);
188 if (PEAR
::isError($err)) { return $err; }
190 $this->printHead($g);
192 $err = $this->generateContent($g);
193 if (PEAR
::isError($err)) { return $err; }
195 $this->printFoot($g);
197 $err = $this->surroundFoot($g);
198 if (PEAR
::isError($err)) { return $err; }
201 function printHead(&$g)
203 if ($this->headFootDisabled()) return;
205 $g->doPrintString('<', $this->_name
);
207 $this->printAttributes($g);
209 if ($this->hasContent() && !$this->_isXHTMLEmptyElement()) {
210 $g->doPrintString('>');
212 $g->doPrintString('/>');
216 function printFoot(&$g)
218 if ($this->headFootDisabled()) return;
220 if ($this->hasContent() && !$this->_isXHTMLEmptyElement()) {
221 $g->doPrintString('</', $this->_name
, '>');
225 function printAttributes(&$g)
227 global $_phptal_xhtml_boolean_attributes;
228 foreach ($this->_attrs
as $key=>$value) {
229 if ($this->_parser
->_outputMode() == PHPTAL_XHTML
230 && in_array(strtolower($key), $_phptal_xhtml_boolean_attributes)) {
231 $g->doPrintString(" $key");
233 $g->doPrintString(" $key=\"$value\"");
238 function surroundHead(&$g)
240 // if some surround attributes, we activate
241 // their header method
242 for ($i=0; $i<count($this->_surround_attributes
); $i++
) {
243 $h =& $this->_surround_attributes
[$i];
244 $err = $h->start($g, $this);
245 if (PEAR
::isError($err)) { return $err; }
250 function surroundFoot(&$g)
252 // close surrounders in reverse order of course
253 for ($i = (count($this->_surround_attributes
)-1); $i >= 0; $i--) {
254 $err = $this->_surround_attributes
[$i]->end($g, $this);
255 if (PEAR
::isError($err)) { return $err; }
259 function generateContent(&$g)
261 if (count($this->_content_attributes
) > 0) {
262 // time for content attributes,
263 foreach ($this->_content_attributes
as $h) {
264 $err = $h->activate($g, $this);
265 if (PEAR
::isError($err)) { return $err; }
268 // if none, we just ask children to generate their code
269 foreach ($this->_children
as $child) {
270 $err = $child->generateCode($g);
271 if (PEAR
::isError($err)) { return $err; }
276 function disableHeadFoot()
278 $this->_head_foot_disabled
= true;
281 function headFootDisabled()
283 return $this->_head_foot_disabled
;print_r($this->_root
);
286 function _isXHTMLEmptyElement()
288 global $_phptal_xhtml_empty_tags;
289 if ($this->_parser
->_outputMode() != PHPTAL_XHTML
) {
292 return in_array(strtoupper($this->name()), $_phptal_xhtml_empty_tags);