====== Embed Plugin ====== ---- plugin ---- description: This plugin allows to embed wikipages seamlessly into another page. In addition, parts marked with the Label Plugin can be replaced. author : Pascal Bihler email : bihler@iai.uni-bonn.de type : syntax lastupdate : 2007-05-14 compatible : 2008-05-05, 2006-11-06, 2007-05-24, 2007-06-26b depends : conflicts : similar : include tags : include, embed downloadurl: http://pb.wh4f.de/dokuwiki/embed.zip ---- ===== The idea ===== Sometimes you are required to include a wikipage while replacing parts of it, e.g. if building up hierarchical menus with the [[:Template#sidebar|Sidebar Template]]. ===== Requirements ===== I've developed the plugin under the DokuWiki version of 2006-11-06 and seems to work with version 2007-06-26 as well. ===== Download / Installation ===== Download the plugin here (manually or via Plugin Manager): http://pb.wh4f.de/dokuwiki/embed.zip ===== Shortcomings ===== To assure proper use of [[:acl|ACLs]], this plugin inhibits caching on pages which make use of the ''%%%%'' tag. ===== Syntax ===== The Syntax is very simple: With replacement: ===== Use Case ===== A use case for this plugin is inherited creation of menus for [[:Template#sidebar|sidebars]], which are reused over different namespaces: **:sidebar** ~~NOTOC~~ * [[:start]] * * * This will look like: * [[:start]] * [[:research:]] * [[:teaching:]] * [[:publications:]] ---- **:teaching:sidebar** (second level) This will look like: * [[:start]] * [[:research:]] * **teaching** * [[.:classes:]] * [[.:labs:]] * [[:publications:]] ---- **:teaching:classes:sidebar** (third level) //(Two replacements!)// This will look like: * [[:start]] * [[:research:]] * [[:teaching]] * **classes** * [[OOSC]] * [[AOSC]] * [[.:labs:]] * [[:publications:]] ===== Code ===== ''(sorry, will be properly indented when I have some time)'' */ // must be run within DokuWiki if(!defined('DOKU_INC')) die(); if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); // class syntax_plugin_embed extends DokuWiki_Syntax_Plugin { function syntax_plugin_embed() { global $embedded_pages_by_plugin_embed; if (! $embedded_pages_by_plugin_embed) { $embedded_pages_by_plugin_embed = array(); // To avoid recursion; } } function getInfo(){ return array( 'author' => 'Pascal Bihler', 'email' => 'bihler@iai.uni-bonn.de', 'date' => '2007-05-14', 'name' => 'Embed', 'desc' => 'Allows to embed wikipages in other ones, while offering the possibility to replace parts of the original page marked with labels.', 'url' => 'https://www.dokuwiki.org/plugin:embed', ); } function getType(){ return 'substition'; } function getSort(){ return 500; } function connectTo($mode) { $this->Lexer->addSpecialPattern(']+\s*>.*?',$mode,'plugin_embed'); $this->Lexer->addSpecialPattern('',$mode,'plugin_embed'); } /** * Handle the match */ function handle($match, $state, $pos, &$handler){ switch ($state) { case DOKU_LEXER_SPECIAL : if (preg_match('/]+)\s*>(.*?)<\/embed>/ms',$match,$matches)) return array($matches[1],$matches[2]); else if (preg_match('/]+)\s*\/>/',$match,$matches)) return array($matches[1],''); break; } return array(); } /** * Create output */ function render($mode, &$renderer, $data) { global $ID; global $embedded_pages_by_plugin_embed; if($mode == 'xhtml'){ list($id,$replacement) = $data; $renderer->info['cache'] = false; // prevent caching (to ensure ACL conformity) (TODO sometimes: make more intelligent) resolve_pageid(getNS($ID), $id, $exists); // resolve shortcuts //resolve_pageid(getNS($ID), $id, $exists); // resolve shortcuts // avoid circular references if (in_array($id,$embedded_pages_by_plugin_embed)) return false; array_push($embedded_pages_by_plugin_embed,$id); $ins = $this->_embed_file($id,$replacement); $renderer->doc .= p_render('xhtml', $ins, $info); // ptype = 'normal' array_pop($embedded_pages_by_plugin_embed); return true; } return false; } function _embed_file($id,$replacement) { // check permission $perm = auth_quickaclcheck($id); if ($perm < AUTH_READ) return false; //Read embeded page $page = io_readfile(wikiFN($id)); // convert relative links $page = $this->_convertInstructions($page,$id); // do replacements (on text-base to preserve List indentation and ordering etc.): $page = $this->_do_replacements($page,$replacement); $ins = p_get_instructions($page); return $ins; } function _do_replacements($page,$r_str) { //Build up list of replacements (this needs to be done manually to allow several replacements with nesting if before ===== Bugs? ===== Getting **Fatal error:** Maximum execution time of 35 seconds exceeded in **lib/plugins/embed/syntax.php on line 139**? Using DokuWiki 2008-05-05. I'm trying to embed 2 pages in one sidebar Some problem with the embedding engine leads to no generation of TOC for %%%%ed headers. Any way to fix this? >I've no clue, since all I do is text-substitution... >> Take a look at the [[plugin:include]] plugin. It does something quite similar to what you are doing and has solved the caching and header issues, you may be able to reuse some of its ideas/code. --- //[[chris@jalakai.co.uk|Christopher Smith]] 2007-07-10 14:29// >>>I started with this plugin, but since it works not on the text, but on the node representation of wikisource, the substitution of elements (via label) was incompatible with the list rendering (and therefore not acceptable) Embeds with absolute internal links go wrong; they come out as ns:ns:page instead of just ns:page. fixed by change line 184 from } elseif (strpos($link, ':') === false){ to } elseif (strpos($link, ':')){ ===== Stopped working ===== I wanted to make a "dynamic mediawiki style infobox" and this was the best plugin for it, until a day it stopped working.