1<?php 2/** 3 * Tag Plugin: displays list of keywords with links to categories this page 4 * belongs to. The links are marked as tags for Technorati and other services 5 * using tagging. 6 * 7 * Usage: {{tag>category tags space separated}} 8 * 9 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 10 * @author Matthias Schulte <dokuwiki@lupo49.de> 11 */ 12 13/** Count syntax, allows to list tag counts */ 14class syntax_plugin_tag_count extends DokuWiki_Syntax_Plugin { 15 16 /** 17 * @return string Syntax type 18 */ 19 function getType() { return 'substition'; } 20 /** 21 * @return int Sort order 22 */ 23 function getSort() { return 305; } 24 /** 25 * @return string Paragraph type 26 */ 27 function getPType() { return 'block';} 28 29 /** 30 * @param string $mode Parser mode 31 */ 32 function connectTo($mode) { 33 $this->Lexer->addSpecialPattern('\{\{count>.*?\}\}', $mode, 'plugin_tag_count'); 34 } 35 36 /** 37 * Handle matches of the count syntax 38 * 39 * @param string $match The match of the syntax 40 * @param int $state The state of the handler 41 * @param int $pos The position in the document 42 * @param Doku_Handler $handler The handler 43 * @return array|false Data for the renderer 44 */ 45 function handle($match, $state, $pos, Doku_Handler $handler) { 46 47 $match = trim(substr($match, 8, -2)); // get given tags 48 [$tags, $nsstring] = array_pad(explode('&', $match,2),2,''); // split to tags and allowed namespaces 49 $allowedNamespaces = explode(' ', $nsstring); // split given namespaces into an array 50 51 if($allowedNamespaces && $allowedNamespaces[0] == '') { 52 unset($allowedNamespaces[0]); // When exists, remove leading space after the delimiter 53 $allowedNamespaces = array_values($allowedNamespaces); 54 } 55 56 if (empty($allowedNamespaces)) { 57 $allowedNamespaces = null; 58 } 59 60 if (!$tags) { 61 $tags = '+'; 62 } 63 64 /** @var helper_plugin_tag $helper */ 65 if(!($helper = $this->loadHelper('tag'))) { 66 return false; 67 } 68 69 return [ 70 $helper->parseTagList($tags), 71 $allowedNamespaces 72 ]; 73 } 74 75 /** 76 * Render xhtml output or metadata 77 * 78 * @param string $format Renderer mode (supported modes: xhtml and metadata) 79 * @param Doku_Renderer $renderer The renderer 80 * @param array $data The data from the handler function 81 * @return bool If rendering was successful. 82 */ 83 function render($format, Doku_Renderer $renderer, $data) { 84 if ($data === false) return false; 85 86 list($tags, $allowedNamespaces) = $data; 87 88 // deactivate (renderer) cache as long as there is no proper cache handling 89 // implemented for the count syntax 90 $renderer->nocache(); 91 92 if($format == "xhtml") { 93 /** @var helper_plugin_tag $helper */ 94 if(!($helper = $this->loadHelper('tag'))) return false; 95 96 // get tags and their occurrences 97 if($tags[0] == '+') { 98 // no tags given, list all tags for allowed namespaces 99 $occurrences = $helper->tagOccurrences($tags, $allowedNamespaces, true); 100 } else { 101 $occurrences = $helper->tagOccurrences($tags, $allowedNamespaces); 102 } 103 104 $class = "inline"; // valid: inline, ul, pagelist 105 $col = "page"; 106 107 $renderer->doc .= '<table class="'.$class.'">'; 108 $renderer->doc .= '<tr>'; 109 $renderer->doc .= '<th class="'.$col.'">'.$this->getLang('tag').'</th>'; 110 $renderer->doc .= '<th class="'.$col.'">'.$this->getLang('count').'</th>'; 111 $renderer->doc .= '</tr>'; 112 113 if(empty($occurrences)) { 114 // Skip output 115 $renderer->doc .= '<tr>'; 116 $renderer->doc .= '<td class="'.$class.'" colspan="2">'.$this->getLang('empty_output').'</td>'; 117 $renderer->doc .= '</tr>'; 118 } else { 119 foreach($occurrences as $tagname => $count) { 120 if($count <= 0) continue; // don't display tags with zero occurrences 121 122 $renderer->doc .= '<tr>'; 123 $renderer->doc .= '<td class="'.$class.'">'.$helper->tagLink($tagname).'</td>'; 124 $renderer->doc .= '<td class="'.$class.'">'.$count.'</td>'; 125 $renderer->doc .= '</tr>'; 126 } 127 } 128 $renderer->doc .= '</table>'; 129 } 130 return true; 131 } 132} 133