xref: /plugin/pagetemplater/action.php (revision 0988efd132e50764725ae824e144caf850fd747b)
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/');
23
24require_once (DOKU_PLUGIN . 'action.php');
25require_once(DOKU_INC . 'inc/pageutils.php');
26
27class action_plugin_pagetemplater extends DokuWiki_Action_Plugin {
28
29    function getInfo(){
30        return array_merge(confToHash(dirname(__FILE__).'/info.txt'), array(
31				'name' => 'Page Templater Action Component',
32		));
33    }
34
35    /**
36     * Register the eventhandlers.
37     */
38    function register(Doku_Event_Handler $controller) {
39        $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, 'handle_content_display', array ());
40        $controller->register_hook('PARSER_METADATA_RENDER', 'AFTER', $this, 'handle_meta_data', array ());
41    }
42
43    function handle_content_display(& $event, $params) {
44		global $ACT, $INFO, $TOC, $ID;
45
46		$template = $this->resolve_template();
47		if ( !$template || $ACT != 'show' ) { return; }
48
49		$oldtoc = $TOC;
50		$template = p_wiki_xhtml( $template );
51
52		// set the replacements
53		$replace = $INFO['meta']['templater'];
54		unset($replace['page']);
55		$replace['content'] = $event->data;
56		$replace['page'] = $ID;
57		$replace['namespace'] = getNS($ID);
58
59		$new = $template;
60		foreach (array_keys($replace) as $key) {
61			if ( $new != $template ) { $template = $new; }
62			if ( $key != 'content' && substr($key, 0, 1) == '!' ) {
63				$rkey = substr($key, 1);
64
65                // When rendering the instructions, there will always be a doc_start/doc_end and another p_open/p_close block. We do not want them.
66				$instructions = array_slice(p_get_instructions($replace[$key]), 2, -2);
67				$replace[$key] = p_render('xhtml', $instructions ,$info);
68			} else { $rkey = $key; }
69			$new = str_replace('@@' . strtoupper(trim($rkey)) . '@@', $replace[$key], $template);
70			$new = str_replace(urlencode('@@') . strtoupper(trim($rkey)) . urlencode('@@'), $replace[$key], $new);
71		}
72
73		if ( $new != $event->data ) {
74			$event->data = $new;
75		}
76
77		$TOC = $oldtoc;
78
79		$data = array('xhtml',& $event->data);
80        trigger_event('RENDERER_CONTENT_POSTPROCESS',$data);
81
82		return true;
83    }
84
85    function handle_meta_data(& $event, $params) {
86		global $ACT;
87
88        $id = getId();
89        if ( $id != $event->data['page'] ) { return true; }
90		$template = $this->resolve_template( $event->data['current']['templater'] );
91		if ( empty( $template) || in_array($template, array( $id, $event->data['page']) ) ) { return true; }
92
93        $meta = p_get_metadata( $template, '', METADATA_RENDER_UNLIMITED );
94
95
96        if ( !$event->data['current']['internal'] || !is_array($event->data['current']['internal']) ) $event->data['current']['internal'] = array();
97        $event->data['current']['internal'] = array_merge($event->data['current']['internal'], $meta['internal']);
98
99        if ( !$event->data['current']['toc'] || !is_array($event->data['current']['toc']) ) $event->data['current']['toc'] = array();
100        $event->data['current']['toc'] = array_merge($event->data['current']['toc'], (array_key_exists('toc', $meta) && is_array($meta['toc'])?$meta['toc']:array()));
101
102/*
103
104		$data = array();
105		$data['internal'] = p_get_metadata( $template, 'internal', METADATA_RENDER_UNLIMITED );
106		$data['toc'] = p_get_metadata( $template, 'toc', METADATA_RENDER_UNLIMITED );
107
108        unset($cache_metadata[$ID]);
109        p_set_metadata( $ID, $data );
110        p_read_metadata( $ID, true );
111        $INFO['meta'] = p_get_metadata($ID, null, METADATA_RENDER_UNLIMITED);
112*/
113		return true;
114    }
115
116    private function resolve_template( $templater = array() ) {
117		global $INFO;
118
119		$page = empty($INFO['meta']['templater']['page']) ? $templater['page'] : $INFO['meta']['templater']['page'];
120
121		// are we in an avtive Namespace?
122		$template = $this->_getActiveNamespace();
123
124		if (!$template && empty( $page ) ) { return; }
125
126		// check for the template
127		return empty( $page ) ? $template : $page;
128    }
129
130    function _getActiveNamespace() {
131    	global $ID;
132    	global $INFO;
133
134// Removed on 2016-09-14
135//		if (!$INFO['exists'])
136//			return false;
137
138    	$pattern = $this->getConf('excluded_pages');
139		if (strlen($pattern) > 0 && preg_match($pattern, $ID)) {
140			return false;
141		}
142
143        $this->loadPages();
144        foreach ($this->pages as $namespace) {
145			$space = cleanID($namespace[0]);
146            if (trim($space) && (strpos($ID, $space . ':') === 0)) {
147                return resolve_id($namespace[0], $namespace[1]);
148            }
149        }
150
151        return false;
152    }
153
154    private static $pages = null;
155    private function loadPages() {
156        if ( $this->pages != null ) {
157            return;
158        }
159
160        $this->pages = array();
161        $namespaces = explode("\n", $this->getConf('enabled_namespaces'));
162        foreach( $namespaces as $namespace ) {
163
164            if ( strlen(trim($namespace)) == 0 ) { continue; }
165            $this->pages[] = explode("=>", $namespace);
166        }
167    }
168}
169
170//Setup VIM: ex: et ts=4 enc=utf-8 :
171