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