2 rcs_id('$Id: Template.php,v 1.67 2004-11-05 18:03:35 rurban Exp $');
4 require_once("lib/ErrorManager.php");
14 function Template ($name, &$request, $args = false) {
17 $this->_request = $request;
19 $request->_TemplatesProcessed[$name] = 1;
20 $this->_basepage = $request->getArg('pagename');
22 $file = $WikiTheme->findTemplate($name);
24 trigger_error("no template for $name found", E_USER_WARNING);
27 $fp = fopen($file, "rb");
29 trigger_error("$file not found", E_USER_WARNING);
32 $this->_tmpl = fread($fp, filesize($file));
34 //$userid = $request->_user->_userid;
36 $this->_locals = $args;
38 $this->_locals = array('CONTENT' => $args);
40 $this->_locals = array();
43 function _munge_input($template) {
45 // Convert < ?plugin expr ? > to < ?php $this->_printPluginPI("expr"); ? >
46 $orig[] = '/<\?plugin.*?\?>/se';
47 $repl[] = "\$this->_mungePlugin('\\0')";
49 // Convert < ?= expr ? > to < ?php $this->_print(expr); ? >
50 $orig[] = '/<\?=(.*?)\?>/s';
51 $repl[] = '<?php $this->_print(\1);?>';
53 return preg_replace($orig, $repl, $template);
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...
61 $pi = preg_replace('/(?!<\\\\)\\\\"/x', '"', $pi);
62 return sprintf('<?php $this->_printPlugin(%s); ?>',
63 "'" . str_replace("'", "\'", $pi) . "'");
66 function _printPlugin ($pi) {
67 include_once("lib/WikiPlugin.php");
71 $loader = new WikiPluginLoader;
73 $this->_print($loader->expandPI($pi, $this->_request, $this, $this->_basepage));
76 function _print ($val) {
77 if (isa($val, 'Template')) {
78 $this->_expandSubtemplate($val);
84 function _expandSubtemplate (&$template) {
86 //if (!$template->_request)
87 // $template->_request = &$this->_request;
88 if (defined('DEBUG') and DEBUG) {
89 echo "<!-- Begin $template->_name -->\n";
91 // Expand sub-template with defaults from this template.
92 $template->printExpansion($this->_vars);
93 if (defined('DEBUG') and DEBUG) {
94 echo "<!-- End $template->_name -->\n";
99 * Substitute HTML replacement text for tokens in template.
101 * Constructs a new WikiTemplate based upon the named template.
105 * @param $token string Name of token to substitute for.
107 * @param $replacement string Replacement HTML text.
109 function replace($varname, $value) {
110 $this->_locals[$varname] = $value;
114 function printExpansion ($defaults = false) {
115 if (!is_array($defaults)) // HTML object or template object
116 $defaults = array('CONTENT' => $defaults);
117 $this->_vars = array_merge($defaults, $this->_locals);
118 extract($this->_vars);
122 $user = $request->getUser();
124 $page = $request->getPage();
126 global $WikiTheme, $RCS_IDS, $charset;
127 //$this->_dump_template();
129 global $ErrorManager;
130 $ErrorManager->pushErrorHandler(new WikiMethodCb($this, '_errorHandler'));
132 eval('?>' . $this->_munge_input($this->_tmpl));
134 $ErrorManager->popErrorHandler();
137 // FIXME: find a way to do template expansion less memory intensive.
138 // 1.3.4 needed no memory at all for dumphtml, now it needs +15MB
139 // Smarty? As before?
140 function getExpansion ($defaults = false) {
142 $this->printExpansion($defaults);
143 $xml = ob_get_contents();
144 ob_end_clean(); // PHP problem: doesn't release its memory?
148 function printXML () {
149 $this->printExpansion();
153 return $this->getExpansion();
158 function _dump_template () {
159 $lines = explode("\n", $this->_munge_input($this->_tmpl));
162 foreach ($lines as $line)
163 $pre->pushContent(fmt("%4d %s\n", $n++, $line));
167 function _errorHandler($error) {
168 //if (!preg_match('/: eval\(\)\'d code$/', $error->errfile))
171 if (preg_match('/: eval\(\)\'d code$/', $error->errfile)) {
172 $error->errfile = "In template '$this->_name'";
173 // Hack alert: Ignore 'undefined variable' messages for variables
174 // whose names are ALL_CAPS.
175 if (preg_match('/Undefined variable:\s*[_A-Z]+\s*$/', $error->errstr))
178 // ignore recursively nested htmldump loop: browse -> body -> htmldump -> browse -> body ...
179 // FIXME for other possible loops also
180 elseif (strstr($error->errfile, "In template 'htmldump'")) {
183 elseif (strstr($error->errfile, "In template '")) { // merge
184 $error->errfile = preg_replace("/'(\w+)'\)$/", "'\\1' < '$this->_name')", $error->errfile);
187 $error->errfile .= " (In template '$this->_name')";
190 if (!empty($this->_tmpl)) {
191 $lines = explode("\n", $this->_tmpl);
192 if (isset($lines[$error->errline - 1]))
193 $error->errstr .= ":\n\t" . $lines[$error->errline - 1];
202 * This is a convenience function and is equivalent to:
207 function Template($name, $args = false) {
209 return new Template($name, $request, $args);
212 function alreadyTemplateProcessed($name) {
214 return !empty($request->_TemplatesProcessed[$name]) ? true : false;
217 * Make and expand the top-level template.
220 * @param $content mixed html content to put into the page
221 * @param $title string page title
222 * @param $page_revision object A WikiDB_PageRevision object
223 * @param $args hash Extract args for top-level template
225 * @return string HTML expansion of template.
227 function GeneratePage($content, $title, $page_revision = false, $args = false) {
230 if (!is_array($args))
233 $args['CONTENT'] = $content;
234 $args['TITLE'] = $title;
235 $args['revision'] = $page_revision;
237 if (!isset($args['HEADER']))
238 $args['HEADER'] = $title;
240 printXML(new Template('html', $request, $args));
245 * For dumping pages as html to a file.
247 function GeneratePageasXML($content, $title, $page_revision = false, $args = false) {
250 if (!is_array($args))
253 $content->_basepage = $title;
254 $args['CONTENT'] = $content;
255 $args['TITLE'] = SplitPagename($title);
256 $args['revision'] = $page_revision;
258 if (!isset($args['HEADER']))
259 $args['HEADER'] = SplitPagename($title);
261 global $HIDE_TOOLBARS, $NO_BASEHREF, $HTML_DUMP;
262 $HIDE_TOOLBARS = true;
265 $html = asXML(new Template('htmldump', $request, $args));
267 $HIDE_TOOLBARS = false;
272 // $Log: not supported by cvs2svn $
273 // Revision 1.66 2004/11/01 10:43:55 rurban
274 // seperate PassUser methods into seperate dir (memory usage)
275 // fix WikiUser (old) overlarge data session
276 // remove wikidb arg from various page class methods, use global ->_dbi instead
279 // Revision 1.65 2004/10/07 16:08:58 rurban
280 // fixed broken FileUser session handling.
281 // thanks to Arnaud Fontaine for detecting this.
282 // enable file user Administrator membership.
284 // Revision 1.64 2004/10/04 23:40:35 rurban
285 // fix nested loops on htmldump errors
287 // Revision 1.63 2004/09/06 08:22:33 rurban
288 // prevent errorhandler to fail on empty templates
290 // Revision 1.62 2004/06/28 15:39:27 rurban
291 // fixed endless recursion in WikiGroup: isAdmin()
293 // Revision 1.61 2004/06/25 14:29:18 rurban
294 // WikiGroup refactoring:
295 // global group attached to user, code for not_current user.
296 // improved helpers for special groups (avoid double invocations)
297 // new experimental config option ENABLE_XHTML_XML (fails with IE, and document.write())
298 // fixed a XHTML validation error on userprefs.tmpl
300 // Revision 1.60 2004/06/14 11:31:36 rurban
301 // renamed global $Theme to $WikiTheme (gforge nameclash)
302 // inherit PageList default options from PageList
303 // default sortby=pagename
304 // use options in PageList_Selectable (limit, sortby, ...)
305 // added action revert, with button at action=diff
306 // added option regex to WikiAdminSearchReplace
308 // Revision 1.59 2004/05/18 16:23:39 rurban
309 // rename split_pagename to SplitPagename
311 // Revision 1.58 2004/05/15 19:48:33 rurban
312 // fix some too loose PagePerms for signed, but not authenticated users
313 // (admin, owner, creator)
314 // no double login page header, better login msg.
315 // moved action_pdf to lib/pdf.php
317 // Revision 1.57 2004/05/01 18:20:05 rurban
318 // Add $charset to template locals (instead of constant CHARSET)
320 // Revision 1.56 2004/04/12 13:04:50 rurban
321 // added auth_create: self-registering Db users
323 // removed rating recommendations
324 // ziplib reformatting
326 // Revision 1.55 2004/04/02 15:06:55 rurban
327 // fixed a nasty ADODB_mysql session update bug
328 // improved UserPreferences layout (tabled hints)
329 // fixed UserPreferences auth handling
330 // improved auth stability
331 // improved old cookie handling: fixed deletion of old cookies with paths
333 // Revision 1.54 2004/03/02 18:11:39 rurban
334 // CreateToc support: Pass the preparsed markup to each plugin as $dbi->_markup
335 // to be able to know about its context, and even let the plugin change it.
338 // Revision 1.53 2004/02/22 23:20:31 rurban
339 // fixed DumpHtmlToDir,
340 // enhanced sortby handling in PageList
341 // new button_heading th style (enabled),
342 // added sortby and limit support to the db backends and plugins
343 // for paging support (<<prev, next>> links on long lists)
345 // Revision 1.52 2003/12/20 23:59:19 carstenklapp
346 // Internal change: Added rcs Log tag & emacs php mode tag (sorry, forgot
347 // this in the last commit).
354 // c-hanging-comment-ender-p: nil
355 // indent-tabs-mode: nil