1<?php 2/** 3 * Tag Plugin, topic component: displays links to all wiki pages with a certain tag 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Esther Brunner <wikidesign@gmail.com> 7 */ 8 9/** 10 * Topic syntax, displays links to all wiki pages with a certain tag 11 */ 12class syntax_plugin_tag_topic extends DokuWiki_Syntax_Plugin { 13 14 /** 15 * @return string Syntax type 16 */ 17 function getType() { return 'substition'; } 18 19 /** 20 * @return string Paragraph type 21 */ 22 function getPType() { return 'block'; } 23 24 /** 25 * @return int Sort order 26 */ 27 function getSort() { return 295; } 28 29 /** 30 * @param string $mode Parser mode 31 */ 32 function connectTo($mode) { 33 //syntax without options catches wrong used syntax too 34 $this->Lexer->addSpecialPattern('\{\{topic>}\}',$mode,'plugin_tag_topic'); 35 $this->Lexer->addSpecialPattern('\{\{topic>.+?\}\}',$mode,'plugin_tag_topic'); 36 } 37 38 /** 39 * Handle matches of the topic syntax 40 * 41 * @param string $match The match of the syntax 42 * @param int $state The state of the handler 43 * @param int $pos The position in the document 44 * @param Doku_Handler $handler The handler 45 * @return array Data for the renderer 46 */ 47 function handle($match, $state, $pos, Doku_Handler $handler) { 48 global $ID; 49 $match = substr($match, 8, -2); // strip {{topic> from start and }} from end 50 list($match, $flags) = array_pad(explode('&', $match, 2), 2, ''); 51 $flags = explode('&', $flags); 52 list($ns, $tag) = array_pad(explode('?', $match), 2, ''); 53 54 if (!$tag) { 55 $tag = $ns; 56 $ns = ''; 57 } 58 59 if ($ns == '*' || $ns == ':') { 60 $ns = ''; 61 } elseif ($ns == '.') { 62 $ns = getNS($ID); 63 } else { 64 $ns = cleanID($ns); 65 } 66 67 return [$ns, trim($tag), $flags]; 68 } 69 70 /** 71 * Render xhtml output or metadata 72 * 73 * @param string $format Renderer mode (supported modes: xhtml and metadata) 74 * @param Doku_Renderer $renderer The renderer 75 * @param array $data The data from the handler function 76 * @return bool If rendering was successful. 77 */ 78 function render($format, Doku_Renderer $renderer, $data) { 79 list($ns, $tag, $flags) = $data; 80 81 /* extract sort flags into array */ 82 $sortflags = []; 83 foreach($flags as $flag) { 84 $separator_pos = strpos($flag, '='); 85 if ($separator_pos === false) { 86 continue; // no "=" found, skip to next flag 87 } 88 89 $conf_name = trim(strtolower(substr($flag, 0 , $separator_pos))); 90 $conf_val = trim(strtolower(substr($flag, $separator_pos+1))); 91 92 if(in_array($conf_name, ['sortkey', 'sortorder'])) { 93 $sortflags[$conf_name] = $conf_val; 94 } 95 } 96 97 /* @var helper_plugin_tag $helper */ 98 if ($helper = $this->loadHelper('tag')) { 99 $helper->overrideSortFlags($sortflags); 100 $pages = $helper->getTopic($ns, '', $tag); 101 } 102 103 if (!isset($pages) || !$pages) return true; // nothing to display 104 105 if ($format == 'xhtml') { 106 /* @var Doku_Renderer_xhtml $renderer */ 107 108 // prevent caching to ensure content is always fresh 109 $renderer->nocache(); 110 111 /* @var helper_plugin_pagelist $pagelist */ 112 // let Pagelist Plugin do the work for us 113 if (!$pagelist = $this->loadHelper('pagelist')) { 114 return false; 115 } 116 $pagelist->sort = false; 117 $pagelist->rsort = false; 118 119 $configflags = explode(',', str_replace(" ", "", $this->getConf('pagelist_flags'))); 120 $flags = array_merge($configflags, $flags); 121 foreach($flags as $key => $flag) { 122 if($flag == "") { 123 unset($flags[$key]); 124 } 125 } 126 127 $pagelist->setFlags($flags); 128 $pagelist->startList(); 129 130 // Sort pages by pagename if required by flags 131 if($pagelist->sort || $pagelist->rsort) { 132 $fnc = function($a, $b) { 133 return strcmp(noNS($a["id"]), noNS($b["id"])); 134 }; 135 usort($pages, $fnc); 136 // rsort is true - revserse sort the pages 137 if($pagelist->rsort) { 138 krsort($pages); 139 } 140 } 141 142 foreach ($pages as $page) { 143 $pagelist->addPage($page); 144 } 145 $renderer->doc .= $pagelist->finishList(); 146 return true; 147 } 148 return false; 149 } 150} 151