171ec1101SGina Haeussge<?php 271ec1101SGina Haeussge/** 371ec1101SGina Haeussge * Include Plugin: displays a wiki page within another 471ec1101SGina Haeussge * Usage: 571ec1101SGina Haeussge * {{page>page}} for "page" in same namespace 671ec1101SGina Haeussge * {{page>:page}} for "page" in top namespace 771ec1101SGina Haeussge * {{page>namespace:page}} for "page" in namespace "namespace" 871ec1101SGina Haeussge * {{page>.namespace:page}} for "page" in subnamespace "namespace" 971ec1101SGina Haeussge * {{page>page#section}} for a section of "page" 1071ec1101SGina Haeussge * 1171ec1101SGina Haeussge * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 1271ec1101SGina Haeussge * @author Esther Brunner <wikidesign@gmail.com> 1371ec1101SGina Haeussge * @author Christopher Smith <chris@jalakai.co.uk> 1471ec1101SGina Haeussge * @author Gina Häußge, Michael Klier <dokuwiki@chimeric.de> 1571ec1101SGina Haeussge */ 1671ec1101SGina Haeussge 1771ec1101SGina Haeussgeif(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 1871ec1101SGina Haeussgeif(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 1971ec1101SGina Haeussgerequire_once(DOKU_PLUGIN.'syntax.php'); 2071ec1101SGina Haeussge 2171ec1101SGina Haeussge/** 2271ec1101SGina Haeussge * All DokuWiki plugins to extend the parser/rendering mechanism 2371ec1101SGina Haeussge * need to inherit from this class 2471ec1101SGina Haeussge */ 2571ec1101SGina Haeussgeclass syntax_plugin_include_include extends DokuWiki_Syntax_Plugin { 2671ec1101SGina Haeussge 27d34e85a5SMichael Hamann /** @var $helper helper_plugin_include */ 2861053b04SMichael Klier var $helper = null; 2961053b04SMichael Klier 30d34e85a5SMichael Hamann /** 31d34e85a5SMichael Hamann * Get syntax plugin type. 32d34e85a5SMichael Hamann * 33d34e85a5SMichael Hamann * @return string The plugin type. 34d34e85a5SMichael Hamann */ 3571ec1101SGina Haeussge function getType() { return 'substition'; } 36d34e85a5SMichael Hamann 37d34e85a5SMichael Hamann /** 38d34e85a5SMichael Hamann * Get sort order of syntax plugin. 39d34e85a5SMichael Hamann * 40d34e85a5SMichael Hamann * @return int The sort order. 41d34e85a5SMichael Hamann */ 4271ec1101SGina Haeussge function getSort() { return 303; } 43d34e85a5SMichael Hamann 44d34e85a5SMichael Hamann /** 45d34e85a5SMichael Hamann * Get paragraph type. 46d34e85a5SMichael Hamann * 47d34e85a5SMichael Hamann * @return string The paragraph type. 48d34e85a5SMichael Hamann */ 4971ec1101SGina Haeussge function getPType() { return 'block'; } 5071ec1101SGina Haeussge 51d34e85a5SMichael Hamann /** 52d34e85a5SMichael Hamann * Connect patterns/modes 53d34e85a5SMichael Hamann * 54d34e85a5SMichael Hamann * @param $mode mixed The current mode 55d34e85a5SMichael Hamann */ 5671ec1101SGina Haeussge function connectTo($mode) { 5771ec1101SGina Haeussge $this->Lexer->addSpecialPattern("{{page>.+?}}", $mode, 'plugin_include_include'); 5871ec1101SGina Haeussge $this->Lexer->addSpecialPattern("{{section>.+?}}", $mode, 'plugin_include_include'); 598b99501bSMichael Klier $this->Lexer->addSpecialPattern("{{namespace>.+?}}", $mode, 'plugin_include_include'); 60a0a6f8fbSMichael Klier $this->Lexer->addSpecialPattern("{{tagtopic>.+?}}", $mode, 'plugin_include_include'); 6171ec1101SGina Haeussge } 6271ec1101SGina Haeussge 63d34e85a5SMichael Hamann /** 64d34e85a5SMichael Hamann * Handle syntax matches 65d34e85a5SMichael Hamann * 66d34e85a5SMichael Hamann * @param string $match The current match 67d34e85a5SMichael Hamann * @param int $state The match state 68d34e85a5SMichael Hamann * @param int $pos The position of the match 69d34e85a5SMichael Hamann * @param Doku_Handler $handler The hanlder object 70d34e85a5SMichael Hamann * @return array The instructions of the plugin 71d34e85a5SMichael Hamann */ 7271ec1101SGina Haeussge function handle($match, $state, $pos, &$handler) { 7371ec1101SGina Haeussge 7471ec1101SGina Haeussge $match = substr($match, 2, -2); // strip markup 7571ec1101SGina Haeussge list($match, $flags) = explode('&', $match, 2); 7671ec1101SGina Haeussge 7761053b04SMichael Klier // break the pattern up into its parts 786f0ad9d7SMichael Klier list($mode, $page, $sect) = preg_split('/>|#/u', $match, 3); 79df062bd2SMichael Hamann $check = false; 805534e4ebSMichael Hamann if (isset($sect)) $sect = sectionID($sect, $check); 81*b0c45c90SMichael Hamann $level = NULL; 82*b0c45c90SMichael Hamann return array($mode, $page, $sect, explode('&', $flags), $level, $pos); 8371ec1101SGina Haeussge } 8471ec1101SGina Haeussge 851a25f14bSMichael Hamann /** 861a25f14bSMichael Hamann * Renders the included page(s) 871a25f14bSMichael Hamann * 881a25f14bSMichael Hamann * @author Michael Hamann <michael@content-space.de> 891a25f14bSMichael Hamann */ 9071ec1101SGina Haeussge function render($format, &$renderer, $data) { 91df062bd2SMichael Hamann global $ID; 921a25f14bSMichael Hamann 931a25f14bSMichael Hamann // static stack that records all ancestors of the child pages 941a25f14bSMichael Hamann static $page_stack = array(); 951a25f14bSMichael Hamann 961a25f14bSMichael Hamann // when there is no id just assume the global $ID is the current id 971a25f14bSMichael Hamann if (empty($page_stack)) $page_stack[] = $ID; 981a25f14bSMichael Hamann 991a25f14bSMichael Hamann $parent_id = $page_stack[count($page_stack)-1]; 1001a25f14bSMichael Hamann $root_id = $page_stack[0]; 1011a25f14bSMichael Hamann 102*b0c45c90SMichael Hamann list($mode, $page, $sect, $flags, $level, $pos) = $data; 1031a25f14bSMichael Hamann 1041a25f14bSMichael Hamann if (!$this->helper) 1051a25f14bSMichael Hamann $this->helper =& plugin_load('helper', 'include'); 1061a25f14bSMichael Hamann $flags = $this->helper->get_flags($flags); 1071a25f14bSMichael Hamann 108ff4c1966SMichael Hamann $pages = $this->helper->_get_included_pages($mode, $page, $sect, $parent_id, $flags); 109791e1550SMichael Hamann 110791e1550SMichael Hamann if ($format == 'metadata') { 111d34e85a5SMichael Hamann /** @var Doku_Renderer_metadata $renderer */ 112560e27a0SMichael Hamann 113560e27a0SMichael Hamann // remove old persistent metadata of previous versions of the include plugin 114560e27a0SMichael Hamann if (isset($renderer->persistent['plugin_include'])) { 115560e27a0SMichael Hamann unset($renderer->persistent['plugin_include']); 116560e27a0SMichael Hamann unset($renderer->meta['plugin_include']); 117560e27a0SMichael Hamann } 118560e27a0SMichael Hamann 119ff4c1966SMichael Hamann $renderer->meta['plugin_include']['instructions'][] = compact('mode', 'page', 'sect', 'parent_id', $flags); 120791e1550SMichael Hamann if (!isset($renderer->meta['plugin_include']['pages'])) 121791e1550SMichael Hamann $renderer->meta['plugin_include']['pages'] = array(); // add an array for array_merge 122791e1550SMichael Hamann $renderer->meta['plugin_include']['pages'] = array_merge($renderer->meta['plugin_include']['pages'], $pages); 123b11b2b9dSMichael Hamann $renderer->meta['plugin_include']['include_content'] = isset($_REQUEST['include_content']); 1241a25f14bSMichael Hamann } 1251a25f14bSMichael Hamann 126*b0c45c90SMichael Hamann $secids = array(); 127*b0c45c90SMichael Hamann if ($format == 'xhtml') { 128*b0c45c90SMichael Hamann $secids = p_get_metadata($ID, 'plugin_include secids'); 129*b0c45c90SMichael Hamann } 130*b0c45c90SMichael Hamann 1311a25f14bSMichael Hamann foreach ($pages as $page) { 132791e1550SMichael Hamann extract($page); 133d34e85a5SMichael Hamann $id = $page['id']; 134d34e85a5SMichael Hamann $exists = $page['exists']; 1351a25f14bSMichael Hamann 136791e1550SMichael Hamann if (in_array($id, $page_stack)) continue; 137791e1550SMichael Hamann array_push($page_stack, $id); 1381a25f14bSMichael Hamann 1396db19c84SMichael Hamann // add references for backlink 14067e87481SMichael Hamann if ($format == 'metadata') { 1416db19c84SMichael Hamann $renderer->meta['relation']['references'][$id] = $exists; 14267e87481SMichael Hamann $renderer->meta['relation']['haspart'][$id] = $exists; 143*b0c45c90SMichael Hamann if (!$sect && !$flags['firstsec'] && !$flags['linkonly'] && !isset($renderer->meta['plugin_include']['secids'][$id])) { 144*b0c45c90SMichael Hamann $renderer->meta['plugin_include']['secids'][$id] = array('hid' => 'plugin_include__'.str_replace(':', '__', $id), 'pos' => $pos); 145*b0c45c90SMichael Hamann } 14667e87481SMichael Hamann } 1476db19c84SMichael Hamann 148*b0c45c90SMichael Hamann if (isset($secids[$id]) && $pos === $secids[$id]['pos']) { 149*b0c45c90SMichael Hamann $flags['include_secid'] = $secids[$id]['hid']; 150*b0c45c90SMichael Hamann } else { 151*b0c45c90SMichael Hamann unset($flags['include_secid']); 152*b0c45c90SMichael Hamann } 153*b0c45c90SMichael Hamann 154*b0c45c90SMichael Hamann $instructions = $this->helper->_get_instructions($id, $sect, $mode, $level, $flags, $root_id, $secids); 155993fccf3SMichael Hamann 1561a25f14bSMichael Hamann $renderer->nest($instructions); 157993fccf3SMichael Hamann 1581a25f14bSMichael Hamann array_pop($page_stack); 1591a25f14bSMichael Hamann } 1601a25f14bSMichael Hamann 1611a25f14bSMichael Hamann // When all includes have been handled remove the current id 1621a25f14bSMichael Hamann // in order to allow the rendering of other pages 1631a25f14bSMichael Hamann if (count($page_stack) == 1) array_pop($page_stack); 1641a25f14bSMichael Hamann 1651a25f14bSMichael Hamann return true; 16661053b04SMichael Klier } 16771ec1101SGina Haeussge} 1682524d407SMichael Hamann// vim:ts=4:sw=4:et: 169