1<?php
2
3/**
4 * Select Template Pages for your Content
5 * The templates Pages have to have the entry @@CONTENT@@
6 * the template per page can be defined using the META plugin
7 *
8 * @license  GPL 2 (http://www.gnu.org/licenses/gpl.html)
9 * @author     i-net software <tools@inetsoftware.de>
10 * @author     Gerry Weissbach <gweissbach@inetsoftware.de>
11 */
12
13// must be run within Dokuwiki
14if (!defined('DOKU_INC'))
15    die();
16
17if (!defined('DOKU_LF'))
18    define('DOKU_LF', "\n");
19if (!defined('DOKU_TAB'))
20    define('DOKU_TAB', "\t");
21if (!defined('DOKU_PLUGIN'))
22    define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
23require_once(DOKU_INC . 'inc/pageutils.php');
24
25class action_plugin_pagetemplater extends DokuWiki_Action_Plugin {
26
27    /**
28     * Register the eventhandlers.
29     */
30    function register(Doku_Event_Handler $controller) {
31        $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, 'handle_content_display', array ());
32        $controller->register_hook('PARSER_METADATA_RENDER', 'AFTER', $this, 'handle_meta_data', array ());
33    }
34
35    function handle_content_display(& $event, $params) {
36        global $ACT, $INFO, $TOC, $ID;
37
38        $template = $this->resolve_template();
39        if ( !$template || $ACT != 'show' ) { return; }
40
41        $oldtoc = $TOC;
42        $template = p_wiki_xhtml( $template );
43
44        // set the replacements
45        $replace = $INFO['meta']['templater'];
46        unset($replace['page']);
47        $replace['content'] = $event->data;
48        $replace['page'] = $ID;
49        $replace['namespace'] = getNS($ID);
50
51        $new = $template;
52        foreach (array_keys($replace) as $key) {
53            if ( $new != $template ) { $template = $new; }
54            if ( $key != 'content' && substr($key, 0, 1) == '!' ) {
55                $rkey = substr($key, 1);
56                $replace[$key] = p_render('xhtml', p_get_instructions($replace[$key]),$info);
57            } else { $rkey = $key; }
58            $new = str_replace('@@' . strtoupper(trim($rkey)) . '@@', $replace[$key], $template);
59            $new = str_replace(urlencode('@@') . strtoupper(trim($rkey)) . urlencode('@@'), $replace[$key], $new);
60        }
61
62        if ( $new != $event->data ) {
63            $event->data = $new;
64        }
65
66        $TOC = $oldtoc;
67
68        $data = array('xhtml',& $event->data);
69        trigger_event('RENDERER_CONTENT_POSTPROCESS',$data);
70
71        return true;
72    }
73
74    function handle_meta_data(& $event, $params) {
75        global $ACT;
76
77        $id = getId();
78        if ( $id != $event->data['page'] ) { return true; }
79        $template = $this->resolve_template( $event->data['current']['templater'] );
80        if ( empty( $template) || in_array($template, array( $id, $event->data['page']) ) ) { return true; }
81
82        $meta = p_get_metadata( $template, '', METADATA_RENDER_UNLIMITED );
83
84
85        if ( !$event->data['current']['internal'] || !is_array($event->data['current']['internal']) ) $event->data['current']['internal'] = array();
86        if ( !is_array($meta['internal']) ) $meta['internal'] = array();
87        $event->data['current']['internal'] = array_merge($event->data['current']['internal'], $meta['internal']);
88
89        if ( !$event->data['current']['toc'] || !is_array($event->data['current']['toc']) ) $event->data['current']['toc'] = array();
90        if ( !is_array($meta['toc']) ) $meta['toc'] = array();
91        $event->data['current']['toc'] = array_merge($event->data['current']['toc'], $meta['toc']);
92
93        return true;
94    }
95
96    private function resolve_template( $templater = array() ) {
97        global $INFO;
98
99        $page = '';
100        if (isset($INFO['meta']['templater']['page']) && !empty($INFO['meta']['templater']['page'])) {
101            $page = $INFO['meta']['templater']['page'];
102        } elseif (isset($templater['page']) && !empty($templater['page'])) {
103            $page = $templater['page'];
104        }
105
106        // are we in an avtive Namespace?
107        $template = $this->_getActiveNamespace();
108        if ( !$template && empty( $page ) ) return;
109
110        return empty( $page ) ? $template : $page;
111    }
112
113    function _getActiveNamespace() {
114        global $ID;
115        global $INFO;
116
117        $pattern = $this->getConf('excluded_pages');
118        if (strlen($pattern) > 0 && preg_match($pattern, $ID)) {
119            return false;
120        }
121
122        $this->loadPages();
123        foreach (self::$pages as $namespace) {
124            $space = cleanID($namespace[0]);
125            if (trim($space) && (strpos($ID, $space . ':') === 0)) {
126                return resolve_id($namespace[0], isset($namespace[1]) ? $namespace[1] : '');
127            }
128        }
129
130        return false;
131    }
132
133    private static $pages = null;
134    private function loadPages() {
135        if ( self::$pages != null ) {
136            return;
137        }
138
139        self::$pages = array();
140        $namespaces = explode("\n", $this->getConf('enabled_namespaces'));
141        foreach( $namespaces as $namespace ) {
142
143            if ( strlen(trim($namespace)) == 0 ) { continue; }
144            self::$pages[] = explode("=>", $namespace);
145        }
146    }
147}
148
149//Setup VIM: ex: et ts=4 enc=utf-8 :
150