1<?php 2/** 3 * DokuWiki Syntax Plugin Combostrap. 4 * 5 */ 6 7use ComboStrap\NavBarUtility; 8use ComboStrap\PluginUtility; 9 10if (!defined('DOKU_INC')) { 11 die(); 12} 13 14require_once(__DIR__ . '/../class/PluginUtility.php'); 15require_once(__DIR__ . '/../class/LinkUtility.php'); 16require_once(__DIR__ . '/../class/HtmlUtility.php'); 17 18/** 19 * All DokuWiki plugins to extend the parser/rendering mechanism 20 * need to inherit from this class 21 * 22 * The name of the class must follow a pattern (don't change it) 23 * ie: 24 * syntax_plugin_PluginName_ComponentName 25 * 26 * A navbar group is a navbar nav 27 */ 28class syntax_plugin_combo_navbargroup extends DokuWiki_Syntax_Plugin 29{ 30 31 const TAG = "group"; 32 const COMPONENT = "navbargroup"; 33 34 /** 35 * Syntax Type. 36 * 37 * Needs to return one of the mode types defined in $PARSER_MODES in parser.php 38 * @see DokuWiki_Syntax_Plugin::getType() 39 */ 40 function getType() 41 { 42 return 'container'; 43 } 44 45 /** 46 * @return array 47 * Allow which kind of plugin inside 48 * All 49 */ 50 public function getAllowedTypes() 51 { 52 return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs'); 53 } 54 55 /** 56 * How Dokuwiki will add P element 57 * 58 * * 'normal' - The plugin can be used inside paragraphs 59 * * 'block' - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs 60 * * 'stack' - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs 61 * 62 * @see DokuWiki_Syntax_Plugin::getPType() 63 */ 64 function getPType() 65 { 66 return 'normal'; 67 } 68 69 /** 70 * @see Doku_Parser_Mode::getSort() 71 * 72 * the mode with the lowest sort number will win out 73 * the container (parent) must then have a lower number than the child 74 */ 75 function getSort() 76 { 77 return 100; 78 } 79 80 /** 81 * Create a pattern that will called this plugin 82 * 83 * @param string $mode 84 * @see Doku_Parser_Mode::connectTo() 85 */ 86 function connectTo($mode) 87 { 88 /** 89 * Only inside a navbar or collapse element 90 */ 91 $authorizedMode = [ 92 PluginUtility::getModeForComponent(syntax_plugin_combo_navbarcollapse::COMPONENT), 93 PluginUtility::getModeForComponent(syntax_plugin_combo_navbar::COMPONENT) 94 ]; 95 96 97 if (in_array($mode, $authorizedMode)) { 98 99 $pattern = PluginUtility::getContainerTagPattern(self::TAG); 100 $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeForComponent($this->getPluginComponent())); 101 102 } 103 104 } 105 106 public function postConnect() 107 { 108 $this->Lexer->addExitPattern('</' . self::TAG . '>', 'plugin_' . PluginUtility::PLUGIN_BASE_NAME . '_' . $this->getPluginComponent()); 109 110 } 111 112 /** 113 * 114 * The handle function goal is to parse the matched syntax through the pattern function 115 * and to return the result for use in the renderer 116 * This result is always cached until the page is modified. 117 * @param string $match 118 * @param int $state 119 * @param int $pos 120 * @param Doku_Handler $handler 121 * @return array|bool 122 * @see DokuWiki_Syntax_Plugin::handle() 123 * 124 */ 125 function handle($match, $state, $pos, Doku_Handler $handler) 126 { 127 128 switch ($state) { 129 130 case DOKU_LEXER_ENTER: 131 132 // Suppress the component name 133 $tagAttributes = PluginUtility::getTagAttributes($match); 134 return array( 135 PluginUtility::STATE => $state, 136 PluginUtility::ATTRIBUTES=> $tagAttributes 137 ); 138 139 case DOKU_LEXER_UNMATCHED: 140 return PluginUtility::handleAndReturnUnmatchedData(self::TAG,$match,$handler); 141 142 143 case DOKU_LEXER_EXIT : 144 145 return array(PluginUtility::STATE => $state); 146 147 148 } 149 150 return array(); 151 152 } 153 154 /** 155 * Render the output 156 * @param string $format 157 * @param Doku_Renderer $renderer 158 * @param array $data - what the function handle() return'ed 159 * @return boolean - rendered correctly? (however, returned value is not used at the moment) 160 * @see DokuWiki_Syntax_Plugin::render() 161 * 162 * 163 */ 164 function render($format, Doku_Renderer $renderer, $data) 165 { 166 167 $state = $data[PluginUtility::STATE]; 168 if ($format == 'xhtml') { 169 170 /** @var Doku_Renderer_xhtml $renderer */ 171 172 switch ($state) { 173 174 case DOKU_LEXER_ENTER : 175 // https://getbootstrap.com/docs/4.0/components/navbar/#toggler splits the navbar-nav to another element 176 // navbar-nav implementation 177 $attributes = $data[PluginUtility::ATTRIBUTES]; 178 $classValue = "navbar-nav"; 179 if (array_key_exists("class", $attributes)) { 180 $attributes["class"] .= " {$classValue}"; 181 } else { 182 $attributes["class"] = $classValue; 183 } 184 185 if (array_key_exists("expand", $attributes)) { 186 if ($attributes["expand"]=="true") { 187 $attributes["class"] .= " mr-auto"; 188 } 189 unset($attributes["expand"]); 190 } 191 192 $inlineAttributes = PluginUtility::array2HTMLAttributes($attributes); 193 $renderer->doc .= "<ul {$inlineAttributes}>" . DOKU_LF; 194 break; 195 case DOKU_LEXER_UNMATCHED : 196 $renderer->doc .= NavBarUtility::text(PluginUtility::renderUnmatched($data)); 197 break; 198 199 case DOKU_LEXER_EXIT : 200 $renderer->doc .= '</ul>' . DOKU_LF; 201 break; 202 } 203 return true; 204 } 205 return false; 206 } 207 208 209} 210