3 require_once 'lib/ErrorManager.php';
10 * name optionally of form "theme/template" to include parent templates in children
13 * @param WikiRequest $request
16 function Template($name, &$request, $args = array())
20 $this->_request =& $request;
21 $this->_basepage = $request->getArg('pagename');
23 if (strstr($name, "/")) {
24 $oldname = $WikiTheme->_name;
25 $oldtheme = $WikiTheme->_theme;
26 list($themename, $name) = explode("/", $name);
27 $WikiTheme->_theme = "themes/$themename";
28 $WikiTheme->_name = $name;
31 $file = $WikiTheme->findTemplate($name);
33 trigger_error("no template for $name found.", E_USER_WARNING);
36 if (isset($oldname)) {
37 $WikiTheme->_name = $oldname;
38 $WikiTheme->_theme = $oldtheme;
40 $fp = fopen($file, "rb");
42 trigger_error("$file not found", E_USER_WARNING);
45 $request->_TemplatesProcessed[$name] = 1;
46 $this->_tmpl = fread($fp, filesize($file));
48 //$userid = $request->_user->_userid;
50 $this->_locals = $args;
52 $this->_locals = array('CONTENT' => $args); else
53 $this->_locals = array();
56 private function _munge_input($template)
59 // Convert < ?plugin expr ? > to < ?php $this->_printPluginPI("expr"); ? >
60 $orig[] = '/<\?plugin.*?\?>/se';
61 $repl[] = "\$this->_mungePlugin('\\0')";
63 // Convert < ?= expr ? > to < ?php $this->_print(expr); ? >
64 $orig[] = '/<\?=(.*?)\?>/s';
65 $repl[] = '<?php $this->_print(\1);?>';
67 // Convert < ?php echo expr ? > to < ?php $this->_print(expr); ? >
68 $orig[] = '/<\?php echo (.*?)\?>/s';
69 $repl[] = '<?php $this->_print(\1);?>';
71 // Avoid PHP 5.5 warning about /e
72 return @preg_replace($orig, $repl, $template);
75 private function _mungePlugin($pi)
77 // HACK ALERT: PHP's preg_replace, with the /e option seems to
78 // escape both single and double quotes with backslashes.
79 // So we need to unescape the double quotes here...
81 $pi = preg_replace('/(?!<\\\\)\\\\"/x', '"', $pi);
82 return sprintf('<?php $this->_printPlugin(%s); ?>',
83 "'" . str_replace("'", "\'", $pi) . "'");
86 private function _printPlugin($pi)
88 include_once 'lib/WikiPlugin.php';
92 $loader = new WikiPluginLoader();
94 $this->_print($loader->expandPI($pi, $this->_request, $this, $this->_basepage));
97 private function _print($val)
99 if (is_a($val, 'Template')) {
100 $this->_expandSubtemplate($val);
106 private function _expandSubtemplate(&$template)
109 //if (!$template->_request)
110 // $template->_request = &$this->_request;
112 echo "<!-- Begin $template->_name -->\n";
114 // Expand sub-template with defaults from this template.
115 $template->printExpansion($this->_vars);
117 echo "<!-- End $template->_name -->\n";
122 * Substitute HTML replacement text for tokens in template.
124 * Constructs a new WikiTemplate based upon the named template.
125 * @param string $varname Name of token to substitute for.
126 * @param string $value Replacement HTML text.
128 public function replace($varname, $value)
130 $this->_locals[$varname] = $value;
133 public function printExpansion($defaults = false)
135 if (!is_array($defaults)) // HTML object or template object
136 $defaults = array('CONTENT' => $defaults);
137 $this->_vars = array_merge($defaults, $this->_locals);
138 extract($this->_vars);
142 $user = $request->getUser();
144 $page = $request->getPage();
145 // Speedup. I checked all templates
146 if (!isset($revision))
150 //$this->_dump_template();
151 $SEP = $WikiTheme->getButtonSeparator();
153 global $ErrorManager;
154 $ErrorManager->pushErrorHandler(new WikiMethodCb($this, '_errorHandler'));
156 eval('?>' . $this->_munge_input($this->_tmpl));
158 $ErrorManager->popErrorHandler();
162 // Find a way to do template expansion less memory intensive and faster.
163 // 1.3.4 needed no memory at all for dumphtml, now it needs +15MB.
164 // Smarty? As before?
165 public function getExpansion($defaults = false)
168 $this->printExpansion($defaults);
169 $xml = ob_get_contents();
170 ob_end_clean(); // PHP problem: Doesn't release its memory?
174 public function printXML()
176 $this->printExpansion();
179 public function asXML()
181 return $this->getExpansion();
185 private function _dump_template()
187 $lines = explode("\n", $this->_munge_input($this->_tmpl));
190 foreach ($lines as $line)
191 $pre->pushContent(fmt("%4d %s\n", $n++, $line));
195 public function _errorHandler($error)
197 //if (!preg_match('/: eval\(\)\'d code$/', $error->errfile))
200 if (preg_match('/: eval\(\)\'d code$/', $error->errfile)) {
201 $error->errfile = "In template '$this->_name'";
202 // Hack alert: Ignore 'undefined variable' messages for variables
203 // whose names are ALL_CAPS.
204 if (preg_match('/Undefined variable:\s*[_A-Z]+\s*$/', $error->errstr))
206 } // ignore recursively nested htmldump loop: browse -> body -> htmldump -> browse -> body ...
207 // FIXME for other possible loops also
208 elseif (strstr($error->errfile, "In template 'htmldump'")) {
210 } elseif (strstr($error->errfile, "In template '")) { // merge
211 $error->errfile = preg_replace("/'(\w+)'\)$/", "'\\1' < '$this->_name')",
214 $error->errfile .= " (In template '$this->_name')";
217 if (!empty($this->_tmpl)) {
218 $lines = explode("\n", $this->_tmpl);
219 if (isset($lines[$error->errline - 1]))
220 $error->errstr .= ":\n\t" . $lines[$error->errline - 1];
229 * This is a convenience function and is equivalent to:
234 function Template($name, $args = array())
237 return new Template($name, $request, $args);
240 function alreadyTemplateProcessed($name)
243 return !empty($request->_TemplatesProcessed[$name]) ? true : false;
247 * Make and expand the top-level template.
250 * @param mixed $content html content to put into the page
251 * @param string $title page title
252 * @param object|bool $page_revision A WikiDB_PageRevision object or false
253 * @param array $args hash Extract args for top-level template
255 function GeneratePage($content, $title, $page_revision = false, $args = array())
259 if (!is_array($args))
262 $args['CONTENT'] = $content;
263 $args['TITLE'] = $title;
264 $args['revision'] = $page_revision;
266 if (!isset($args['HEADER']))
267 $args['HEADER'] = $title;
269 printXML(new Template('html', $request, $args));
273 * For dumping pages as html to a file.
274 * Used for action=dumphtml,action=ziphtml,format=pdf,format=xml
276 function GeneratePageasXML($content, $title, $page_revision = null, $args = array())
280 if (!is_array($args))
283 $content->_basepage = $title;
284 $args['CONTENT'] = $content;
285 $args['TITLE'] = SplitPagename($title);
286 $args['revision'] = $page_revision;
288 if (!isset($args['HEADER']))
289 $args['HEADER'] = SplitPagename($title);
291 global $HIDE_TOOLBARS, $WikiTheme;
292 $HIDE_TOOLBARS = true;
293 if (!$WikiTheme->DUMP_MODE)
294 $WikiTheme->DUMP_MODE = 'HTML';
296 // FIXME: unfatal errors and login requirements
297 $html = asXML(new Template('htmldump', $request, $args));
299 $HIDE_TOOLBARS = false;
300 //$WikiTheme->DUMP_MODE = false;
308 // c-hanging-comment-ender-p: nil
309 // indent-tabs-mode: nil