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 Esther Brunner <wikidesign@gmail.com> 11 */ 12 13/** 14 * Tag syntax plugin, allows to specify tags in a page 15 */ 16class syntax_plugin_tag_tag extends DokuWiki_Syntax_Plugin { 17 18 /** 19 * @return string Syntax type 20 */ 21 function getType() { return 'substition'; } 22 /** 23 * @return int Sort order 24 */ 25 function getSort() { return 305; } 26 /** 27 * @return string Paragraph type 28 */ 29 function getPType() { return 'block';} 30 31 /** 32 * @param string $mode Parser mode 33 */ 34 function connectTo($mode) { 35 $this->Lexer->addSpecialPattern('\{\{tag>.*?\}\}', $mode, 'plugin_tag_tag'); 36 } 37 38 /** 39 * Handle matches of the tag 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|false Data for the renderer 46 */ 47 function handle($match, $state, $pos, Doku_Handler $handler) { 48 $tags = trim(substr($match, 6, -2)); // strip markup & whitespace 49 $tags = trim($tags, "\xe2\x80\x8b"); // strip word/wordpad breaklines 50 $tags = preg_replace(['/[[:blank:]]+/', '/\s+/'], " ", $tags); // replace linebreaks and multiple spaces with one space character 51 $tags = preg_replace('/[\x00-\x1F\x7F]/u', '', $tags); // strip unprintable ascii code out of utf-8 coded string 52 53 if (!$tags) return false; 54 55 // load the helper_plugin_tag 56 /** @var helper_plugin_tag $helper */ 57 if (!$helper = $this->loadHelper('tag')) { 58 return false; 59 } 60 61 // split tags and returns for renderer 62 return $helper->parseTagList($tags); 63 } 64 65 /** 66 * Render xhtml output or metadata 67 * 68 * @param string $format Renderer mode (supported modes: xhtml and metadata) 69 * @param Doku_Renderer $renderer The renderer 70 * @param array $data The data from the handler function 71 * @return bool If rendering was successful. 72 */ 73 function render($format, Doku_Renderer $renderer, $data) { 74 if ($data === false) return false; 75 /** @var helper_plugin_tag $helper */ 76 if (!$helper = $this->loadHelper('tag')) return false; 77 78 // XHTML output 79 if ($format == 'xhtml') { 80 $tags = $helper->tagLinks($data); 81 if (!$tags) { 82 return true; 83 } 84 $renderer->doc .= '<div class="'.$this->getConf('tags_list_css').'">' 85 . '<span>'.DOKU_LF 86 . DOKU_TAB.$tags.DOKU_LF 87 . '</span>' 88 . '</div>'.DOKU_LF; 89 return true; 90 91 // for metadata renderer 92 } elseif ($format == 'metadata') { 93 /** @var Doku_Renderer_metadata $renderer */ 94 // erase tags on persistent metadata no more used 95 if (isset($renderer->persistent['subject'])) { 96 unset($renderer->persistent['subject']); 97 $renderer->meta['subject'] = []; 98 } 99 100 if (!isset($renderer->meta['subject'])) { 101 $renderer->meta['subject'] = []; 102 } 103 104 // each registered tags in metadata and index should be valid IDs 105 $data = array_map('cleanID', $data); 106 // merge with previous tags and make the values unique 107 $renderer->meta['subject'] = array_unique(array_merge($renderer->meta['subject'], $data)); 108 109 if ($renderer->capture) { 110 $renderer->doc .= DOKU_LF.implode(' ', $data).DOKU_LF; 111 } 112 113 // add references if tag page exists 114 foreach ($data as $tag) { 115 // resolve shortcuts 116 // Igor and later 117 if (class_exists('dokuwiki\File\PageResolver')) { 118 $resolver = new dokuwiki\File\PageResolver($helper->getNamespace() . ':something'); 119 $tag = $resolver->resolveId($tag); 120 } else { 121 // Compatibility with older releases 122 resolve_pageid($helper->getNamespace(), $tag, $exists); 123 } 124 $renderer->meta['relation']['references'][$tag] = page_exists($tag); 125 } 126 127 return true; 128 } 129 return false; 130 } 131} 132