]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/Template.php
renamed global $Theme to $WikiTheme (gforge nameclash)
[SourceForge/phpwiki.git] / lib / Template.php
1 <?php //-*-php-*-
2 rcs_id('$Id: Template.php,v 1.60 2004-06-14 11:31:36 rurban Exp $');
3
4 require_once("lib/ErrorManager.php");
5
6
7 /** An HTML template.
8  */
9 class Template
10 {
11     /**
12      *
13      */
14     function Template ($name, &$request, $args = false) {
15         global $WikiTheme;
16
17         $this->_request = &$request;
18         $this->_name = $name;
19         $GLOBALS['TemplatesProcessed'][$name] = 1;
20         $this->_basepage = $request->getArg('pagename');
21         
22         $file = $WikiTheme->findTemplate($name);
23         if (!$file) {
24             trigger_error("no template for $name found", E_USER_WARNING);
25             return;
26         }
27         $fp = fopen($file, "rb");
28         if (!$fp) {
29             trigger_error("$file not found", E_USER_WARNING);
30             return;
31         }
32         $this->_tmpl = fread($fp, filesize($file));
33         fclose($fp);
34         //$userid = $request->_user->_userid;
35         if (is_array($args))
36             $this->_locals = $args;
37         elseif ($args)
38             $this->_locals = array('CONTENT' => $args);
39         else
40             $this->_locals = array();
41     }
42
43     function _munge_input($template) {
44
45         // Convert < ?plugin expr ? > to < ?php $this->_printPluginPI("expr"); ? >
46         $orig[] = '/<\?plugin.*?\?>/se';
47         $repl[] = "\$this->_mungePlugin('\\0')";
48         
49         // Convert < ?= expr ? > to < ?php $this->_print(expr); ? >
50         $orig[] = '/<\?=(.*?)\?>/s';
51         $repl[] = '<?php $this->_print(\1);?>';
52         
53         return preg_replace($orig, $repl, $template);
54     }
55
56     function _mungePlugin($pi) {
57         // HACK ALERT: PHP's preg_replace, with the /e option seems to
58         // escape both single and double quotes with backslashes.
59         // So we need to unescape the double quotes here...
60
61         $pi = preg_replace('/(?!<\\\\)\\\\"/x', '"', $pi);
62         return sprintf('<?php $this->_printPlugin(%s); ?>',
63                        "'" . str_replace("'", "\'", $pi) . "'");
64     }
65     
66     function _printPlugin ($pi) {
67         include_once("lib/WikiPlugin.php");
68         static $loader;
69
70         if (empty($loader))
71             $loader = new WikiPluginLoader;
72         
73         $this->_print($loader->expandPI($pi, $this->_request, $this, $this->_basepage));
74     }
75     
76     function _print ($val) {
77         if (isa($val, 'Template'))
78             $this->_expandSubtemplate($val);
79         else
80             PrintXML($val);
81     }
82
83     function _expandSubtemplate (&$template) {
84         // FIXME: big hack!        
85         if (!$template->_request)
86             $template->_request = &$this->_request;
87         if (defined('DEBUG') and DEBUG) {
88             echo "<!-- Begin $template->_name -->\n";
89         }
90         // Expand sub-template with defaults from this template.
91         $template->printExpansion($this->_vars);
92         if (defined('DEBUG') and DEBUG) {
93             echo "<!-- End $template->_name -->\n";
94         }
95     }
96         
97     /**
98      * Substitute HTML replacement text for tokens in template. 
99      *
100      * Constructs a new WikiTemplate based upon the named template.
101      *
102      * @access public
103      *
104      * @param $token string Name of token to substitute for.
105      *
106      * @param $replacement string Replacement HTML text.
107      */
108     function replace($varname, $value) {
109         $this->_locals[$varname] = $value;
110     }
111
112     
113     function printExpansion ($defaults = false) {
114         if (!is_array($defaults))
115             $defaults = array('CONTENT' => $defaults);
116         $this->_vars = array_merge($defaults, $this->_locals);
117         extract($this->_vars);
118
119         $request = &$this->_request;
120         if (!isset($user))
121             $user = &$request->getUser();
122         if (!isset($page))
123             $page = &$request->getPage();
124         
125         global $WikiTheme, $RCS_IDS, $charset;
126         
127         //$this->_dump_template();
128
129         global $ErrorManager;
130         $ErrorManager->pushErrorHandler(new WikiMethodCb($this, '_errorHandler'));
131
132         eval('?>' . $this->_munge_input($this->_tmpl));
133
134         $ErrorManager->popErrorHandler();
135     }
136
137     function getExpansion ($defaults = false) {
138         ob_start();
139         $this->printExpansion($defaults);
140         $xml = ob_get_contents();
141         ob_end_clean();
142         return $xml;
143     }
144
145     function printXML () {
146         $this->printExpansion();
147     }
148
149     function asXML () {
150         return $this->getExpansion();
151     }
152     
153             
154     // Debugging:
155     function _dump_template () {
156         $lines = explode("\n", $this->_munge_input($this->_tmpl));
157         $pre = HTML::pre();
158         $n = 1;
159         foreach ($lines as $line)
160             $pre->pushContent(fmt("%4d  %s\n", $n++, $line));
161         $pre->printXML();
162     }
163
164     function _errorHandler($error) {
165         //if (!preg_match('/: eval\(\)\'d code$/', $error->errfile))
166         //    return false;
167
168         if (preg_match('/: eval\(\)\'d code$/', $error->errfile)) {
169             $error->errfile = "In template '$this->_name'";
170             // Hack alert: Ignore 'undefined variable' messages for variables
171             //  whose names are ALL_CAPS.
172             if (preg_match('/Undefined variable:\s*[_A-Z]+\s*$/', $error->errstr))
173                 return true;
174         }
175         else
176             $error->errfile .= " (In template '$this->_name')";
177         
178         $lines = explode("\n", $this->_tmpl);
179         if (isset($lines[$error->errline - 1]))
180             $error->errstr .= ":\n\t" . $lines[$error->errline - 1];
181         return $error;
182     }
183 };
184
185 /**
186  * Get a templates
187  *
188  * This is a convenience function and is equivalent to:
189  * <pre>
190  *   new Template(...)
191  * </pre>
192  */
193 function Template($name, $args = false) {
194     global $request;
195     return new Template($name, $request, $args);
196 }
197
198 function alreadyTemplateProcessed($name) {
199     return !empty($GLOBALS['TemplatesProcessed'][$name]) ? true : false;
200 }
201 /**
202  * Make and expand the top-level template. 
203  *
204  *
205  * @param $content mixed html content to put into the page
206  * @param $title string page title
207  * @param $page_revision object A WikiDB_PageRevision object
208  * @param $args hash Extract args for top-level template
209  *
210  * @return string HTML expansion of template.
211  */
212 function GeneratePage($content, $title, $page_revision = false, $args = false) {
213     global $request;
214     
215     if (!is_array($args))
216         $args = array();
217
218     $args['CONTENT'] = $content;
219     $args['TITLE'] = $title;
220     $args['revision'] = $page_revision;
221     
222     if (!isset($args['HEADER']))
223         $args['HEADER'] = $title;
224     
225     printXML(new Template('html', $request, $args));
226 }
227
228
229 /**
230  * For dumping pages as html to a file.
231  */
232 function GeneratePageasXML($content, $title, $page_revision = false, $args = false) {
233     global $request;
234     
235     if (!is_array($args))
236         $args = array();
237
238     $content->_basepage = $title;
239     $args['CONTENT'] = $content;
240     $args['TITLE'] = SplitPagename($title);
241     $args['revision'] = $page_revision;
242     
243     if (!isset($args['HEADER']))
244         $args['HEADER'] = SplitPagename($title);
245     
246     global $HIDE_TOOLBARS, $NO_BASEHREF, $HTML_DUMP;
247     $HIDE_TOOLBARS = true;
248     $HTML_DUMP = true;
249
250     $html = asXML(new Template('htmldump', $request, $args));
251
252     $HIDE_TOOLBARS = false;
253     $HTML_DUMP = false;
254     return $html;
255 }
256
257 // $Log: not supported by cvs2svn $
258 // Revision 1.59  2004/05/18 16:23:39  rurban
259 // rename split_pagename to SplitPagename
260 //
261 // Revision 1.58  2004/05/15 19:48:33  rurban
262 // fix some too loose PagePerms for signed, but not authenticated users
263 //  (admin, owner, creator)
264 // no double login page header, better login msg.
265 // moved action_pdf to lib/pdf.php
266 //
267 // Revision 1.57  2004/05/01 18:20:05  rurban
268 // Add $charset to template locals (instead of constant CHARSET)
269 //
270 // Revision 1.56  2004/04/12 13:04:50  rurban
271 // added auth_create: self-registering Db users
272 // fixed IMAP auth
273 // removed rating recommendations
274 // ziplib reformatting
275 //
276 // Revision 1.55  2004/04/02 15:06:55  rurban
277 // fixed a nasty ADODB_mysql session update bug
278 // improved UserPreferences layout (tabled hints)
279 // fixed UserPreferences auth handling
280 // improved auth stability
281 // improved old cookie handling: fixed deletion of old cookies with paths
282 //
283 // Revision 1.54  2004/03/02 18:11:39  rurban
284 // CreateToc support: Pass the preparsed markup to each plugin as $dbi->_markup
285 // to be able to know about its context, and even let the plugin change it.
286 // (see CreateToc)
287 //
288 // Revision 1.53  2004/02/22 23:20:31  rurban
289 // fixed DumpHtmlToDir,
290 // enhanced sortby handling in PageList
291 //   new button_heading th style (enabled),
292 // added sortby and limit support to the db backends and plugins
293 //   for paging support (<<prev, next>> links on long lists)
294 //
295 // Revision 1.52  2003/12/20 23:59:19  carstenklapp
296 // Internal change: Added rcs Log tag & emacs php mode tag (sorry, forgot
297 // this in the last commit).
298 //
299
300 // Local Variables:
301 // mode: php
302 // tab-width: 8
303 // c-basic-offset: 4
304 // c-hanging-comment-ender-p: nil
305 // indent-tabs-mode: nil
306 // End:   
307 ?>