]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/Template.php
Minor internal change: Reformatted DEBUGging output of templates.
[SourceForge/phpwiki.git] / lib / Template.php
1 <?php rcs_id('$Id: Template.php,v 1.51 2003-12-20 23:54:15 carstenklapp Exp $');
2
3 require_once("lib/ErrorManager.php");
4
5
6 /** An HTML template.
7  */
8 class Template
9 {
10     /**
11      *
12      */
13     function Template ($name, &$request, $args = false) {
14         global $Theme;
15
16         $this->_request = &$request;
17         $this->_name = $name;
18         $this->_basepage = $request->getArg('pagename');
19         
20         $file = $Theme->findTemplate($name);
21         $fp = fopen($file, "rb");
22         $this->_tmpl = fread($fp, filesize($file));
23         fclose($fp);
24
25         if (is_array($args))
26             $this->_locals = $args;
27         elseif ($args)
28             $this->_locals = array('CONTENT' => $args);
29         else
30             $this->_locals = array();
31     }
32
33     function _munge_input($template) {
34
35         // Convert < ?plugin expr ? > to < ?php $this->_printPluginPI("expr"); ? >
36         $orig[] = '/<\?plugin.*?\?>/se';
37         $repl[] = "\$this->_mungePlugin('\\0')";
38         
39         // Convert < ?= expr ? > to < ?php $this->_print(expr); ? >
40         $orig[] = '/<\?=(.*?)\?>/s';
41         $repl[] = '<?php $this->_print(\1);?>';
42         
43         return preg_replace($orig, $repl, $template);
44     }
45
46     function _mungePlugin($pi) {
47         // HACK ALERT: PHP's preg_replace, with the /e option seems to
48         // escape both single and double quotes with backslashes.
49         // So we need to unescape the double quotes here...
50
51         $pi = preg_replace('/(?!<\\\\)\\\\"/x', '"', $pi);
52         return sprintf('<?php $this->_printPlugin(%s); ?>',
53                        "'" . str_replace("'", "\'", $pi) . "'");
54     }
55     
56     function _printPlugin ($pi) {
57         include_once("lib/WikiPlugin.php");
58         static $loader;
59
60         if (empty($loader))
61             $loader = new WikiPluginLoader;
62         
63         $this->_print($loader->expandPI($pi, $this->_request, $this->_basepage));
64     }
65     
66     function _print ($val) {
67         if (isa($val, 'Template'))
68             $this->_expandSubtemplate($val);
69         else
70             PrintXML($val);
71     }
72
73     function _expandSubtemplate (&$template) {
74         // FIXME: big hack!        
75         if (!$template->_request)
76             $template->_request = &$this->_request;
77         if (defined('DEBUG') and DEBUG) {
78             echo "<!-- Begin $template->_name -->\n";
79         }
80         // Expand sub-template with defaults from this template.
81         $template->printExpansion($this->_vars);
82         if (defined('DEBUG') and DEBUG) {
83             echo "<!-- End $template->_name -->\n";
84         }
85     }
86         
87     /**
88      * Substitute HTML replacement text for tokens in template. 
89      *
90      * Constructs a new WikiTemplate based upon the named template.
91      *
92      * @access public
93      *
94      * @param $token string Name of token to substitute for.
95      *
96      * @param $replacement string Replacement HTML text.
97      */
98     function replace($varname, $value) {
99         $this->_locals[$varname] = $value;
100     }
101
102     
103     function printExpansion ($defaults = false) {
104         if (!is_array($defaults))
105             $defaults = array('CONTENT' => $defaults);
106         $this->_vars = array_merge($defaults, $this->_locals);
107         extract($this->_vars);
108
109         $request = &$this->_request;
110         if (!isset($user))
111             $user = &$request->getUser();
112         if (!isset($page))
113             $page = &$request->getPage();
114         
115         global $Theme, $RCS_IDS;
116
117         
118         
119         //$this->_dump_template();
120
121         global $ErrorManager;
122         $ErrorManager->pushErrorHandler(new WikiMethodCb($this, '_errorHandler'));
123
124         eval('?>' . $this->_munge_input($this->_tmpl));
125
126         $ErrorManager->popErrorHandler();
127     }
128
129     function getExpansion ($defaults = false) {
130         ob_start();
131         $this->printExpansion($defaults);
132         $xml = ob_get_contents();
133         ob_end_clean();
134         return $xml;
135     }
136
137     function printXML () {
138         $this->printExpansion();
139     }
140
141     function asXML () {
142         return $this->getExpansion();
143     }
144     
145             
146     // Debugging:
147     function _dump_template () {
148         $lines = explode("\n", $this->_munge_input($this->_tmpl));
149         $pre = HTML::pre();
150         $n = 1;
151         foreach ($lines as $line)
152             $pre->pushContent(fmt("%4d  %s\n", $n++, $line));
153         $pre->printXML();
154     }
155
156     function _errorHandler($error) {
157         //if (!preg_match('/: eval\(\)\'d code$/', $error->errfile))
158         //    return false;
159
160         if (preg_match('/: eval\(\)\'d code$/', $error->errfile)) {
161             $error->errfile = "In template '$this->_name'";
162             // Hack alert: Ignore 'undefined variable' messages for variables
163             //  whose names are ALL_CAPS.
164             if (preg_match('/Undefined variable:\s*[_A-Z]+\s*$/', $error->errstr))
165                 return true;
166         }
167         else
168             $error->errfile .= " (In template '$this->_name')";
169         
170         $lines = explode("\n", $this->_tmpl);
171         if (isset($lines[$error->errline - 1]))
172             $error->errstr .= ":\n\t" . $lines[$error->errline - 1];
173         return $error;
174     }
175 };
176
177 /**
178  * Get a templates
179  *
180  * This is a convenience function and is equivalent to:
181  * <pre>
182  *   new Template(...)
183  * </pre>
184  */
185 function Template($name, $args = false) {
186     global $request;
187     return new Template($name, $request, $args);
188 }
189
190 /**
191  * Make and expand the top-level template. 
192  *
193  *
194  * @param $content mixed html content to put into the page
195  * @param $title string page title
196  * @param $page_revision object A WikiDB_PageRevision object
197  * @param $args hash Extract args for top-level template
198  *
199  * @return string HTML expansion of template.
200  */
201 function GeneratePage($content, $title, $page_revision = false, $args = false) {
202     global $request;
203     
204     if (!is_array($args))
205         $args = array();
206
207     $args['CONTENT'] = $content;
208     $args['TITLE'] = $title;
209     $args['revision'] = $page_revision;
210     
211     if (!isset($args['HEADER']))
212         $args['HEADER'] = $title;
213     
214     printXML(new Template('html', $request, $args));
215 }
216
217
218 /**
219  * For dumping pages as html to a file.
220  */
221 function GeneratePageasXML($content, $title, $page_revision = false, $args = false) {
222     global $request;
223     
224     if (!is_array($args))
225         $args = array();
226
227     $args['CONTENT'] = $content;
228     $args['TITLE'] = split_pagename($title);
229     $args['revision'] = $page_revision;
230     
231     if (!isset($args['HEADER']))
232         $args['HEADER'] = split_pagename($title);
233     
234     global $HIDE_TOOLBARS, $NO_BASEHREF, $HTML_DUMP;
235     $HIDE_TOOLBARS = true;
236     $HTML_DUMP = true;
237
238     $html = asXML(new Template('htmldump', $request, $args));
239
240     $HIDE_TOOLBARS = false;
241     $HTML_DUMP = false;
242     return $html;
243 }
244
245
246 // Local Variables:
247 // mode: php
248 // tab-width: 8
249 // c-basic-offset: 4
250 // c-hanging-comment-ender-p: nil
251 // indent-tabs-mode: nil
252 // End:   
253 ?>