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