3 require_once 'lib/ErrorManager.php';
10 * name optionally of form "theme/template" to include parent templates in children
12 function Template ($name, &$request, $args = false) {
15 $this->_request =& $request;
16 $this->_basepage = $request->getArg('pagename');
18 if (strstr($name, "/")) {
19 $oldname = $WikiTheme->_name;
20 $oldtheme = $WikiTheme->_theme;
21 list($themename, $name) = explode("/", $name);
22 $WikiTheme->_theme = "themes/$themename";
23 $WikiTheme->_name = $name;
26 $file = $WikiTheme->findTemplate($name);
28 trigger_error("no template for $name found.", E_USER_WARNING);
31 if (isset($oldname)) {
32 $WikiTheme->_name = $oldname;
33 $WikiTheme->_theme = $oldtheme;
35 $fp = fopen($file, "rb");
37 trigger_error("$file not found", E_USER_WARNING);
40 $request->_TemplatesProcessed[$name] = 1;
41 $this->_tmpl = fread($fp, filesize($file));
43 //$userid = $request->_user->_userid;
45 $this->_locals = $args;
47 $this->_locals = array('CONTENT' => $args);
49 $this->_locals = array();
52 function _munge_input($template) {
54 // Convert < ?plugin expr ? > to < ?php $this->_printPluginPI("expr"); ? >
55 $orig[] = '/<\?plugin.*?\?>/se';
56 $repl[] = "\$this->_mungePlugin('\\0')";
58 // Convert < ?= expr ? > to < ?php $this->_print(expr); ? >
59 $orig[] = '/<\?=(.*?)\?>/s';
60 $repl[] = '<?php $this->_print(\1);?>';
62 // Convert < ?php echo expr ? > to < ?php $this->_print(expr); ? >
63 $orig[] = '/<\?php echo (.*?)\?>/s';
64 $repl[] = '<?php $this->_print(\1);?>';
66 return preg_replace($orig, $repl, $template);
69 function _mungePlugin($pi) {
70 // HACK ALERT: PHP's preg_replace, with the /e option seems to
71 // escape both single and double quotes with backslashes.
72 // So we need to unescape the double quotes here...
74 $pi = preg_replace('/(?!<\\\\)\\\\"/x', '"', $pi);
75 return sprintf('<?php $this->_printPlugin(%s); ?>',
76 "'" . str_replace("'", "\'", $pi) . "'");
79 function _printPlugin ($pi) {
80 include_once 'lib/WikiPlugin.php';
84 $loader = new WikiPluginLoader;
86 $this->_print($loader->expandPI($pi, $this->_request, $this, $this->_basepage));
89 function _print ($val) {
90 if (isa($val, 'Template')) {
91 $this->_expandSubtemplate($val);
97 function _expandSubtemplate (&$template) {
99 //if (!$template->_request)
100 // $template->_request = &$this->_request;
102 echo "<!-- Begin $template->_name -->\n";
104 // Expand sub-template with defaults from this template.
105 $template->printExpansion($this->_vars);
107 echo "<!-- End $template->_name -->\n";
112 * Substitute HTML replacement text for tokens in template.
114 * Constructs a new WikiTemplate based upon the named template.
118 * @param $token string Name of token to substitute for.
120 * @param $replacement string Replacement HTML text.
122 function replace($varname, $value) {
123 $this->_locals[$varname] = $value;
127 function printExpansion ($defaults = false) {
128 if (!is_array($defaults)) // HTML object or template object
129 $defaults = array('CONTENT' => $defaults);
130 $this->_vars = array_merge($defaults, $this->_locals);
131 extract($this->_vars);
135 $user = $request->getUser();
137 $page = $request->getPage();
138 // Speedup. I checked all templates
139 if (!isset($revision))
142 global $WikiTheme, $charset;
143 //$this->_dump_template();
144 $SEP = $WikiTheme->getButtonSeparator();
146 global $ErrorManager;
147 $ErrorManager->pushErrorHandler(new WikiMethodCb($this, '_errorHandler'));
149 eval('?>' . $this->_munge_input($this->_tmpl));
151 $ErrorManager->popErrorHandler();
155 // Find a way to do template expansion less memory intensive and faster.
156 // 1.3.4 needed no memory at all for dumphtml, now it needs +15MB.
157 // Smarty? As before?
158 function getExpansion ($defaults = false) {
160 $this->printExpansion($defaults);
161 $xml = ob_get_contents();
162 ob_end_clean(); // PHP problem: Doesn't release its memory?
166 function printXML () {
167 $this->printExpansion();
171 return $this->getExpansion();
176 function _dump_template () {
177 $lines = explode("\n", $this->_munge_input($this->_tmpl));
180 foreach ($lines as $line)
181 $pre->pushContent(fmt("%4d %s\n", $n++, $line));
185 function _errorHandler($error) {
186 //if (!preg_match('/: eval\(\)\'d code$/', $error->errfile))
189 if (preg_match('/: eval\(\)\'d code$/', $error->errfile)) {
190 $error->errfile = "In template '$this->_name'";
191 // Hack alert: Ignore 'undefined variable' messages for variables
192 // whose names are ALL_CAPS.
193 if (preg_match('/Undefined variable:\s*[_A-Z]+\s*$/', $error->errstr))
196 // ignore recursively nested htmldump loop: browse -> body -> htmldump -> browse -> body ...
197 // FIXME for other possible loops also
198 elseif (strstr($error->errfile, "In template 'htmldump'")) {
201 elseif (strstr($error->errfile, "In template '")) { // merge
202 $error->errfile = preg_replace("/'(\w+)'\)$/", "'\\1' < '$this->_name')",
206 $error->errfile .= " (In template '$this->_name')";
209 if (!empty($this->_tmpl)) {
210 $lines = explode("\n", $this->_tmpl);
211 if (isset($lines[$error->errline - 1]))
212 $error->errstr .= ":\n\t" . $lines[$error->errline - 1];
221 * This is a convenience function and is equivalent to:
226 function Template($name, $args = false) {
228 return new Template($name, $request, $args);
231 function alreadyTemplateProcessed($name) {
233 return !empty($request->_TemplatesProcessed[$name]) ? true : false;
236 * Make and expand the top-level template.
239 * @param $content mixed html content to put into the page
240 * @param $title string page title
241 * @param $page_revision object A WikiDB_PageRevision object or false
242 * @param $args hash Extract args for top-level template
244 * @return string HTML expansion of template.
246 function GeneratePage($content, $title, $page_revision = false, $args = false) {
249 if (!is_array($args))
252 $args['CONTENT'] = $content;
253 $args['TITLE'] = $title;
254 $args['revision'] = $page_revision;
256 if (!isset($args['HEADER']))
257 $args['HEADER'] = $title;
259 printXML(new Template('html', $request, $args));
264 * For dumping pages as html to a file.
265 * Used for action=dumphtml,action=ziphtml,format=pdf,format=xml
267 function GeneratePageasXML($content, $title, $page_revision = false, $args = false) {
270 if (!is_array($args))
273 $content->_basepage = $title;
274 $args['CONTENT'] = $content;
275 $args['TITLE'] = SplitPagename($title);
276 $args['revision'] = $page_revision;
278 if (!isset($args['HEADER']))
279 $args['HEADER'] = SplitPagename($title);
281 global $HIDE_TOOLBARS, $NO_BASEHREF, $WikiTheme;
282 $HIDE_TOOLBARS = true;
283 if (!$WikiTheme->DUMP_MODE)
284 $WikiTheme->DUMP_MODE = 'HTML';
286 // FIXME: unfatal errors and login requirements
287 $html = asXML(new Template('htmldump', $request, $args));
289 $HIDE_TOOLBARS = false;
290 //$WikiTheme->DUMP_MODE = false;
298 // c-hanging-comment-ender-p: nil
299 // indent-tabs-mode: nil