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// must be run within Dokuwiki 14if (!defined('DOKU_INC')) die(); 15 16if (!defined('DOKU_LF')) define('DOKU_LF', "\n"); 17if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t"); 18if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 19 20if ( class_exists('syntax_plugin_tag_tag') ) { 21 22 /** 23 * Tag syntax plugin, allows to specify tags in a page 24 */ 25 class syntax_plugin_tagsections_tag extends syntax_plugin_tag_tag { 26 27 function __construct() { 28 if (plugin_isdisabled('tag') || (!$this->Htag = plugin_load('helper', 'tag'))) { 29 msg('tag plugin is required by tagsections plugin, but missing', -1); 30 return false; 31 } 32 } 33 34 /** 35 * @return string Syntax type 36 */ 37 function getType() { return 'baseonly'; } 38 /** 39 * @return int Sort order 40 */ 41 function getSort() { return 300; } 42 43 /** 44 * @param string $mode Parser mode 45 */ 46 function connectTo($mode) { 47 $this->Lexer->addSpecialPattern('\{\{tag>.*?\}\}', $mode, 'plugin_tagsections_tag'); 48 } 49 50 /** 51 * Render xhtml output or metadata 52 * 53 * @param string $mode Renderer mode (supported modes: xhtml and metadata) 54 * @param Doku_Renderer $renderer The renderer 55 * @param array $data The data from the handler function 56 * @return bool If rendering was successful. 57 */ 58 function render($mode, Doku_Renderer $renderer, $data) { 59 60 if ($data === false) return false; 61 62 // XHTML output 63 if ($mode == 'xhtml') { 64 65 // If we are directly after an opening Tag of a section level. This only applies if the option is enabled. 66 $secLevelRegex = '/<h([1-9])(.*?)(>.*?)(<\/h\1>\s*?)(<div class=")(level\1)(">\s*?)/s'; 67 $matches = array(); 68 69 if ( preg_match_all($secLevelRegex, $renderer->doc, $matches, PREG_SET_ORDER) ) { 70 71 $matches = array_pop($matches); 72 $levelTags = $tags = implode(' ', array_map(array($this, '__tags'), $data)); 73 $tagList = implode('', array_map(array($this, '__tagList'), $data)); 74 75 $matches[2] = preg_replace("/(class=\")(.*?)/", "$1$tags $2", $matches[2]); 76 77 if ( !$this->getConf('addTagsToSectionElements') ) { 78 $levelTags = ''; 79 } 80 81 $renderer->doc = str_replace($matches[0], "<h{$matches[1]}{$matches[2]}{$matches[3]}$tagList{$matches[4]}{$matches[5]}$levelTags {$matches[6]}{$matches[7]}", $renderer->doc); 82 83 return true; 84 } 85 } 86 87 return parent::render($mode, $renderer, $data); 88 } 89 90 function __clean($entry) { 91 return cleanID(str_replace(':', '_', $entry)); 92 } 93 94 function __tags($entry) { 95 $entries = explode(':', $entry); 96 return implode(' ', array_unique(array_merge($entries, array($this->__clean($entry))))); 97 } 98 99 function __tagList($entry) { 100 101 $entries = explode(':', $entry); 102 $list = array_unique(array_merge($entries, array($this->__clean($entry)))); 103 104 if ( ($my = $this->loadHelper('tag')) && $this->getConf('useTagLinks')) { 105 return '<span class="tagsections header tag '.implode(' ', $list).'">'.$my->tagLink($entry, array_pop($entries)).'</span>'; 106 } else { 107 108 $name = array_pop($entries); 109 $format = $this->getConf('alternateLinkFormat'); 110 if ( !empty($format) ) { 111 $format = str_replace(array( "{TAG}", "{NAME}", "{RAW}" ), array( urlencode(cleanID($entry)), urlencode(cleanID($name)), cleanID($entry) ), $format); 112 $link = tpl_link($format, $name, 'rel="tag" title="'.$entry.'"', true); 113 } else { 114 $link = $name; 115 } 116 117 return '<span class="tagsections header tag '.implode(' ', $list).'">'.$link.'</span>'; 118 } 119 } 120 } 121} 122// vim:ts=4:sw=4:et: 123