]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/Template.php
silence missing page warning
[SourceForge/phpwiki.git] / lib / plugin / Template.php
1 <?php // -*-php-*-
2 rcs_id('$Id: Template.php,v 1.9 2007-03-04 14:09:13 rurban Exp $');
3 /*
4  Copyright 2005 $ThePhpWikiProgrammingTeam
5
6  This file is part of PhpWiki.
7
8  PhpWiki is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12
13  PhpWiki is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with PhpWiki; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 /**
24  * Template: Parametrized blocks.
25  *    Include text from a wiki page and replace certain placeholders by parameters.
26  *    Similiar to CreatePage with the template argument, but at run-time.
27  *    Similiar to the mediawiki templates but not with the "|" parameter seperator.
28  * Usage:   <?plugin Template page=TemplateFilm vars="title=rurban&year=1999" ?>
29  * Author:  Reini Urban
30  * See also: http://meta.wikimedia.org/wiki/Help:Template
31  *
32  * Parameter expansion:
33  *   vars="var1=value1&var2=value2"
34  * We only support named parameters, not numbered ones as in mediawiki, and 
35  * the placeholder is %%var%% and not {{{var}}} as in mediawiki.
36  *
37  * The following predefined variables are automatically expanded if existing:
38  *   pagename
39  *   mtime     - last modified date + time
40  *   ctime     - creation date + time
41  *   author    - last author
42  *   owner     
43  *   creator   - first author
44  *   SERVER_URL, DATA_PATH, SCRIPT_NAME, PHPWIKI_BASE_URL and BASE_URL
45  *
46  * <noinclude> .. </noinclude> is stripped
47  *
48  * See also:
49  * - ENABLE_MARKUP_TEMPLATE = true: (lib/InlineParser.php)
50  *   Support a mediawiki-style syntax extension which maps 
51  *     {{TemplateFilm|title=Some Good Film|year=1999}}
52  *   to 
53  *     <?plugin Template page=TemplateFilm vars="title=Some Good Film&year=1999" ?>
54  */
55
56 class WikiPlugin_Template
57 extends WikiPlugin
58 {
59     function getName() {
60         return _("Template");
61     }
62
63     function getDescription() {
64         return _("Parametrized page inclusion.");
65     }
66
67     function getVersion() {
68         return preg_replace("/[Revision: $]/", '',
69                             "\$Revision: 1.9 $");
70     }
71
72     function getDefaultArguments() {
73         return array( 
74                      'page'    => false, // the page to include
75                      'vars'    => false, // TODO: get rid of this, all remaining args should be vars
76                      'rev'     => false, // the revision (defaults to most recent)
77                      'section' => false, // just include a named section
78                      'sectionhead' => false // when including a named section show the heading
79                      );
80     }
81     function allow_undeclared_arg($name, $value) {
82         // either just allow it or you can store it here away also. 
83         $this->vars[$name] = $value;
84         return $name != 'action';
85     }
86     // TODO: check if page can really be pulled from the args, or if it is just the basepage. 
87     function getWikiPageLinks($argstr, $basepage) {
88         $args = $this->getArgs($argstr);
89         $page = @$args['page'];
90         if ($page) {
91             // Expand relative page names.
92             $page = new WikiPageName($page, $basepage);
93         }
94         if (!$page or !$page->name)
95             return false;
96         return array(array('linkto' => $page->name, 'relation' => 0));
97     }
98                 
99     function run($dbi, $argstr, &$request, $basepage) {
100         $this->vars = array();
101         $args = $this->getArgs($argstr, $request);
102         $vars = $args['vars'] ? $args['vars'] : $this->vars;
103         $page = $args['page'];
104         if ($page) {
105             // Expand relative page names.
106             $page = new WikiPageName($page, $basepage);
107             $page = $page->name;
108         }
109         if (!$page) {
110             return $this->error(_("no page specified"));
111         }
112
113         // Protect from recursive inclusion. A page can include itself once
114         static $included_pages = array();
115         if (in_array($page, $included_pages)) {
116             return $this->error(sprintf(_("recursive inclusion of page %s"),
117                                         $page));
118         }
119
120         $p = $dbi->getPage($page);
121         if ($args['rev']) {
122             $r = $p->getRevision($args['rev']);
123             if (!$r) {
124                 return $this->error(sprintf(_("%s(%d): no such revision"),
125                                             $page, $args['rev']));
126             }
127         } else {
128             $r = $p->getCurrentRevision();
129         }
130         $initial_content = $r->getPackedContent();
131         $c = explode("\n", $initial_content);
132
133         if ($args['section']) {
134             $c = extractSection($args['section'], $c, $page, $quiet, $args['sectionhead']);
135             $initial_content = implode("\n", $c);
136         }
137
138         if (preg_match('/<noinclude>.+<\/noinclude>/s', $initial_content)) {
139             $initial_content = preg_replace("/<noinclude>.+?<\/noinclude>/s", "", 
140                                             $initial_content);
141         }
142         $this->doVariableExpansion($initial_content, $vars, $basepage, $request);
143
144         array_push($included_pages, $page);
145
146         include_once('lib/BlockParser.php');
147         $content = TransformText($initial_content, $r->get('markup'), $page);
148
149         array_pop($included_pages);
150
151         return HTML::div(array('class' => 'template'), $content);
152     }
153
154     /**
155      * Expand template variables. Used by the TemplatePlugin and the CreatePagePlugin
156      */
157     function doVariableExpansion(&$content, $vars, $basepage, &$request) {
158         if (preg_match('/%%\w+%%/', $content)) // need variable expansion
159         {
160             $dbi =& $request->_dbi;
161             $var = array();
162             if (is_string($vars) and !empty($vars)) {
163                 foreach (split("&",$vars) as $pair) {
164                     list($key,$val) = split("=",$pair);
165                     $var[$key] = $val;
166                 }
167             } elseif (is_array($vars)) {
168                 $var =& $vars;
169             }
170             $thispage = $dbi->getPage($basepage);
171             // pagename and userid are not overridable
172             $var['PAGENAME'] = $thispage->getName();
173             if (preg_match('/%%USERID%%/', $content))
174                 $var['USERID'] = $request->_user->getId();
175             if (empty($var['MTIME']) and preg_match('/%%MTIME%%/', $content)) {
176                 $thisrev  = $thispage->getCurrentRevision(false);
177                 $var['MTIME'] = $GLOBALS['WikiTheme']->formatDateTime($thisrev->get('mtime'));
178             }
179             if (empty($var['CTIME']) and preg_match('/%%CTIME%%/', $content)) {
180                 if ($first = $thispage->getRevision(1,false))
181                     $var['CTIME'] = $GLOBALS['WikiTheme']->formatDateTime($first->get('mtime'));
182             }
183             if (empty($var['AUTHOR']) and preg_match('/%%AUTHOR%%/', $content))
184                 $var['AUTHOR'] = $thispage->getAuthor();
185             if (empty($var['OWNER']) and preg_match('/%%OWNER%%/', $content))
186                 $var['OWNER'] = $thispage->getOwner();
187             if (empty($var['CREATOR']) and preg_match('/%%CREATOR%%/', $content))
188                 $var['CREATOR'] = $thispage->getCreator();
189             foreach (array("SERVER_URL", "DATA_PATH", "SCRIPT_NAME", "PHPWIKI_BASE_URL") as $c) {
190                 // constants are not overridable
191                 if (preg_match('/%%'.$c.'%%/', $content))
192                     $var[$c] = constant($c);
193             }
194             if (preg_match('/%%BASE_URL%%/', $content))
195                 $var['BASE_URL'] = PHPWIKI_BASE_URL;
196
197             foreach ($var as $key => $val) {
198                 //$content = preg_replace("/%%".preg_quote($key,"/")."%%/", $val, $content);
199                 $content = str_replace("%%".$key."%%", $val, $content);
200             }
201         }
202         return $content;
203     }
204 };
205
206 // $Log: not supported by cvs2svn $
207 // Revision 1.8  2007/01/25 07:42:29  rurban
208 // Changed doVariableExpansion API. Uppercase default vars. Use str_replace.
209 //
210 // Revision 1.7  2007/01/04 16:42:41  rurban
211 // Improve vars passing. Use new method allow_undeclared_arg to allow arbitrary args for the template. Fix doVariableExpansion: use a ref. Fix pagename. Put away \b in regex.
212 //
213 // Revision 1.6  2007/01/03 21:24:06  rurban
214 // protect page in links. new doVariableExpansion() for CreatePage. preg_quote custom vars.
215 //
216 // Revision 1.5  2006/04/17 17:28:21  rurban
217 // honor getWikiPageLinks change linkto=>relation
218 //
219 // Revision 1.4  2005/09/11 13:30:22  rurban
220 // improve comments
221 //
222 // Revision 1.3  2005/09/10 20:43:19  rurban
223 // support <noinclude>
224 //
225 // Revision 1.2  2005/09/10 20:07:16  rurban
226 // fix BASE_URL
227 //
228 // Revision 1.1  2005/09/10 19:59:38  rurban
229 // Parametrized page inclusion ala mediawiki
230 //
231
232 // For emacs users
233 // Local Variables:
234 // mode: php
235 // tab-width: 8
236 // c-basic-offset: 4
237 // c-hanging-comment-ender-p: nil
238 // indent-tabs-mode: nil
239 // End:
240 ?>