]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/Template.php
LANG still broken, working on better locale handling.
[SourceForge/phpwiki.git] / lib / Template.php
1 <?php rcs_id('$Id: Template.php,v 1.41 2002-08-27 21:51:31 rurban Exp $');
2
3 require_once("lib/ErrorManager.php");
4 require_once("lib/WikiPlugin.php");
5
6
7 /** An HTML template.
8  */
9 class Template
10 {
11     /**
12      *
13      */
14     function Template ($name, &$request, $args = false) {
15         global $Theme;
16
17         $this->_request = &$request;
18         $this->_name = $name;
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         static $loader;
58
59         if (empty($loader))
60             $loader = new WikiPluginLoader;
61         
62         $this->_print($loader->expandPI($pi, $this->_request));
63     }
64     
65     function _print ($val) {
66         if (isa($val, 'Template'))
67             $this->_expandSubtemplate($val);
68         else
69             PrintXML($val);
70     }
71
72     function _expandSubtemplate (&$template) {
73         // FIXME: big hack!        
74         if (!$template->_request)
75             $template->_request = &$this->_request;
76         
77         echo "<!-- Begin $template->_name -->\n";
78         // Expand sub-template with defaults from this template.
79         $template->printExpansion($this->_vars);
80         echo "<!-- End $template->_name -->\n";
81     }
82         
83     /**
84      * Substitute HTML replacement text for tokens in template. 
85      *
86      * Constructs a new WikiTemplate based upon the named template.
87      *
88      * @access public
89      *
90      * @param $token string Name of token to substitute for.
91      *
92      * @param $replacement string Replacement HTML text.
93      */
94     function replace($varname, $value) {
95         $this->_locals[$varname] = $value;
96     }
97
98     
99     function printExpansion ($defaults = false) {
100         if (!is_array($defaults))
101             $defaults = array('CONTENT' => $defaults);
102         $this->_vars = array_merge($defaults, $this->_locals);
103         extract($this->_vars);
104
105         $request = &$this->_request;
106         $user = &$request->getUser();
107         $page = &$request->getPage();
108
109         global $Theme, $RCS_IDS;
110         
111         //$this->_dump_template();
112
113         global $ErrorManager;
114         $ErrorManager->pushErrorHandler(new WikiMethodCb($this, '_errorHandler'));
115
116         eval('?>' . $this->_munge_input($this->_tmpl));
117
118         $ErrorManager->popErrorHandler();
119     }
120
121     function getExpansion ($defaults = false) {
122         ob_start();
123         $this->printExpansion($defaults);
124         $xml = ob_get_contents();
125         ob_end_clean();
126         return $xml;
127     }
128
129     function printXML () {
130         $this->printExpansion();
131     }
132
133     function asXML () {
134         return $this->getExpansion();
135     }
136     
137             
138     // Debugging:
139     function _dump_template () {
140         $lines = explode("\n", $this->_munge_input($this->_tmpl));
141         $pre = HTML::pre();
142         $n = 1;
143         foreach ($lines as $line)
144             $pre->pushContent(fmt("%4d  %s\n", $n++, $line));
145         $pre->printXML();
146     }
147
148     function _errorHandler($error) {
149         //if (!preg_match('/: eval\(\)\'d code$/', $error->errfile))
150         //    return false;
151
152         
153         if (preg_match('/: eval\(\)\'d code$/', $error->errfile)) {
154             $error->errfile = "In template '$this->_name'";
155             // Hack alert: Ignore 'undefined variable' messages for variables
156             //  whose names are ALL_CAPS.
157             if (preg_match('/Undefined variable:\s*[_A-Z]+\s*$/', $error->errstr))
158                 return true;
159         }
160         else
161             $error->errfile .= "(In template '$this->_name'?)";
162         
163         $lines = explode("\n", $this->_tmpl);
164         
165         if (isset($lines[$error->errline - 1]))
166             $error->errstr .= ":\n\t" . $lines[$error->errline - 1];
167         return $error;
168     }
169 };
170
171 /**
172  * Get a templates
173  *
174  * This is a convenience function and is equivalent to:
175  * <pre>
176  *   new Template(...)
177  * </pre>
178  */
179 function Template($name, $args = false) {
180     global $request;
181     return new Template($name, $request, $args);
182 }
183
184 /**
185  * Make and expand the top-level template. 
186  *
187  *
188  * @param $content mixed html content to put into the page
189  * @param $title string page title
190  * @param $page_revision object A WikiDB_PageRevision object
191  * @param $args hash Extract args for top-level template
192  *
193  * @return string HTML expansion of template.
194  */
195 function GeneratePage($content, $title, $page_revision = false, $args = false) {
196     global $request;
197     
198     if (!is_array($args))
199         $args = array();
200
201     $args['CONTENT'] = $content;
202     $args['TITLE'] = $title;
203     $args['revision'] = $page_revision;
204     
205     if (!isset($args['HEADER']))
206         $args['HEADER'] = $title;
207     
208     if ($frame = $request->getArg('frame')) {
209         if ($frame == 'top') $args['framesrc'] = $request->getArg('framesrc');
210         printXML(new Template($frame, $request, $args));
211         $request->setArg('framesrc',false);
212     } else {
213         // Early plugin-head check:
214         // head plugins must consist of a single line at the VERY FIRST LINE in the content.
215         // This is a hack, but it works fast enough.
216         if ($page_revision and 
217             $text = &$page_revision->getPackedContent() and 
218             strstr($text, '<?plugin-head'))
219         {
220             $loader = new WikiPluginLoader();
221             // CheckMe!
222             return $loader->expandPI('<\?plugin-head\s+(?!\S)',$request);
223             /* // the return of FrameInclude:
224                $plugin = TransformText($page_revision);
225                $args['FRAMESET'] = $plugin->_content[0];
226                printXML(new Template('frameset', $request, $args));
227             */
228         } else {
229             printXML(new Template('html', $request, $args));
230         }
231     }
232 }
233
234
235 /**
236  * For dumping pages as html to a file.
237  */
238 function GeneratePageasXML($content, $title, $page_revision = false, $args = false) {
239     global $request;
240     
241     if (!is_array($args))
242         $args = array();
243
244     $args['CONTENT'] = $content;
245     $args['TITLE'] = split_pagename($title);
246     $args['revision'] = $page_revision;
247     
248     if (!isset($args['HEADER']))
249         $args['HEADER'] = split_pagename($title);
250     
251     global $HIDE_TOOLBARS, $NO_BASEHREF, $HTML_DUMP;
252     $HIDE_TOOLBARS = true;
253     $HTML_DUMP = true;
254
255     $html = asXML(new Template('htmldump', $request, $args));
256
257     $HIDE_TOOLBARS = false;
258     $HTML_DUMP = false;
259     return $html;
260 }
261
262
263 // Local Variables:
264 // mode: php
265 // tab-width: 8
266 // c-basic-offset: 4
267 // c-hanging-comment-ender-p: nil
268 // indent-tabs-mode: nil
269 // End:   
270 ?>