]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/Template.php
Hackish fixes for some problems with ViewSource.
[SourceForge/phpwiki.git] / lib / Template.php
1 <?php rcs_id('$Id: Template.php,v 1.31 2002-01-25 00:32:39 dairiki Exp $');
2
3 require_once("lib/ErrorManager.php");
4 require_once("lib/WikiPlugin.php");
5 require_once("lib/ButtonFactory.php");
6
7
8 /** An HTML template.
9  */
10 class Template
11 {
12     /**
13      *
14      */
15     function Template ($name, &$request, $args = false) {
16         global $Theme;
17
18         $this->_request = &$request;
19         $this->_name = $name;
20
21         $file = $Theme->findTemplate($name);
22         $fp = fopen($file, "rb");
23         $this->_tmpl = fread($fp, filesize($file));
24         fclose($fp);
25
26         if (is_array($args))
27             $this->_locals = $args;
28         elseif ($args)
29             $this->_locals = array('CONTENT' => $args);
30         else
31             $this->_locals = array();
32     }
33
34     function _munge_input($template) {
35
36         // Convert < ?plugin expr ? > to < ?php $this->_printPluginPI("expr"); ? >
37         $orig[] = '/<\?plugin.*?\?>/se';
38         $repl[] = "\$this->_mungePlugin('\\0')";
39         
40         // Convert < ?= expr ? > to < ?php $this->_print(expr); ? >
41         $orig[] = '/<\?=(.*?)\?>/s';
42         $repl[] = '<?php $this->_print(\1);?>';
43         
44         return preg_replace($orig, $repl, $template);
45     }
46
47     function _mungePlugin($pi) {
48         // HACK ALERT: PHP's preg_replace, with the /e option seems to
49         // escape both single and double quotes with backslashes.
50         // So we need to unescape the double quotes here...
51
52         $pi = preg_replace('/(?!<\\\\)\\\\"/x', '"', $pi);
53         return sprintf('<?php $this->_printPlugin(%s); ?>',
54                        "'" . str_replace("'", "\'", $pi) . "'");
55     }
56     
57     function _printPlugin ($pi) {
58         static $loader;
59
60         if (empty($loader))
61             $loader = new WikiPluginLoader;
62         
63         $this->_print($loader->expandPI($pi, $this->_request));
64     }
65     
66     function _print ($val) {
67         if (isa($val, 'Template'))
68             $this->_expandSubtemplate($val);
69         else
70             PrintXML($val);
71     }
72
73     function _expandSubtemplate (&$template) {
74         // FIXME: big hack!        
75         if (!$template->_request)
76             $template->_request = &$this->_request;
77         
78         echo "<!-- Begin $template->_name -->\n";
79         // Expand sub-template with defaults from this template.
80         $template->printExpansion($this->_vars);
81         echo "<!-- End $template->_name -->\n";
82     }
83         
84     /**
85      * Substitute HTML replacement text for tokens in template. 
86      *
87      * Constructs a new WikiTemplate based upon the named template.
88      *
89      * @access public
90      *
91      * @param $token string Name of token to substitute for.
92      *
93      * @param $replacement string Replacement HTML text.
94      */
95     function replace($varname, $value) {
96         $this->_locals[$varname] = $value;
97     }
98
99     
100     function printExpansion ($defaults = false) {
101         if (!is_array($defaults))
102             $defaults = array('CONTENT' => $defaults);
103         $this->_vars = array_merge($defaults, $this->_locals);
104         extract($this->_vars);
105
106         $request = &$this->_request;
107         $user = &$request->getUser();
108         $page = &$request->getPage();
109
110         global $Theme, $RCS_IDS;
111         $ButtonFactory = new ButtonFactory($request);
112         
113         //$this->_dump_template();
114
115         global $ErrorManager;
116         $ErrorManager->pushErrorHandler(new WikiMethodCb($this, '_errorHandler'));
117
118         eval('?>' . $this->_munge_input($this->_tmpl));
119
120         $ErrorManager->popErrorHandler();
121     }
122
123     function getExpansion ($defaults = false) {
124         ob_start();
125         $this->printExpansion($defaults);
126         $xml = ob_get_contents();
127         ob_end_clean();
128         return $xml;
129     }
130
131     function printXML () {
132         $this->printExpansion();
133     }
134
135     function asXML () {
136         return $this->getExpansion();
137     }
138     
139             
140     // Debugging:
141     function _dump_template () {
142         $lines = explode("\n", $this->_munge_input($this->_tmpl));
143         $pre = HTML::pre();
144         $n = 1;
145         foreach ($lines as $line)
146             $pre->pushContent(fmt("%4d  %s\n", $n++, $line));
147         $pre->printXML();
148     }
149
150     function _errorHandler($error) {
151         //if (!preg_match('/: eval\(\)\'d code$/', $error->errfile))
152         //    return false;
153
154         
155         if (preg_match('/: eval\(\)\'d code$/', $error->errfile)) {
156             $error->errfile = "In template '$this->_name'";
157             // Hack alert: Ignore 'undefined variable' messages for variables
158             //  whose names are ALL_CAPS.
159             if (preg_match('/Undefined variable:\s*[_A-Z]+\s*$/', $error->errstr))
160                 return true;
161         }
162         else
163             $error->errfile .= "(In template '$this->_name'?)";
164         
165         $lines = explode("\n", $this->_tmpl);
166         
167         if (isset($lines[$error->errline - 1]))
168             $error->errstr .= ":\n\t" . $lines[$error->errline - 1];
169         return $error;
170     }
171 };
172
173 /**
174  * Get a templates
175  *
176  * This is a convenience function and is equivalent to:
177  * <pre>
178  *   new Template(...)
179  * </pre>
180  */
181 function Template($name, $args = false) {
182     global $request;
183     return new Template($name, $request, $args);
184 }
185
186 /**
187  * Make and expand the top-level template. 
188  *
189  *
190  * @param $content mixed html content to put into the page
191  * @param $title string page title
192  * @param $page_revision object A WikiDB_PageRevision object
193  * @param $args hash Extract args for top-level template
194  *
195  * @return string HTML expansion of template.
196  */
197 function GeneratePage($content, $title, $page_revision = false, $args = false) {
198     global $request;
199     
200     if (!is_array($args))
201         $args = array();
202
203     $args['CONTENT'] = $content;
204     $args['TITLE'] = $title;
205     $args['revision'] = $page_revision;
206     
207     if (!isset($args['HEADER']))
208         $args['HEADER'] = $title;
209     
210     printXML(new Template('top', $request, $args));
211 }
212
213
214 // Local Variables:
215 // mode: php
216 // tab-width: 8
217 // c-basic-offset: 4
218 // c-hanging-comment-ender-p: nil
219 // indent-tabs-mode: nil
220 // End:   
221 ?>