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