xref: /plugin/combo/syntax/accordion.php (revision 5f891b7e09648e05e78f5882f3fdde1e9df9b0f1) !
1*5f891b7eSNickeau<?php
2*5f891b7eSNickeau/**
3*5f891b7eSNickeau * DokuWiki Syntax Plugin Combostrap.
4*5f891b7eSNickeau *
5*5f891b7eSNickeau */
6*5f891b7eSNickeau
7*5f891b7eSNickeauuse ComboStrap\PluginUtility;
8*5f891b7eSNickeauuse ComboStrap\Tag;
9*5f891b7eSNickeau
10*5f891b7eSNickeauif (!defined('DOKU_INC')) {
11*5f891b7eSNickeau    die();
12*5f891b7eSNickeau}
13*5f891b7eSNickeau
14*5f891b7eSNickeauif (!defined('DOKU_PLUGIN')) {
15*5f891b7eSNickeau    define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
16*5f891b7eSNickeau}
17*5f891b7eSNickeau
18*5f891b7eSNickeaurequire_once(__DIR__ . '/../class/PluginUtility.php');
19*5f891b7eSNickeau
20*5f891b7eSNickeau/**
21*5f891b7eSNickeau * All DokuWiki plugins to extend the parser/rendering mechanism
22*5f891b7eSNickeau * need to inherit from this class
23*5f891b7eSNickeau *
24*5f891b7eSNickeau * The name of the class must follow a pattern (don't change it)
25*5f891b7eSNickeau * ie:
26*5f891b7eSNickeau *    syntax_plugin_PluginName_ComponentName
27*5f891b7eSNickeau *
28*5f891b7eSNickeau * https://getbootstrap.com/docs/4.6/components/collapse/#accordion-example
29*5f891b7eSNickeau *
30*5f891b7eSNickeau * Ter info:
31*5f891b7eSNickeau * https://jqueryui.com/accordion/
32*5f891b7eSNickeau */
33*5f891b7eSNickeauclass syntax_plugin_combo_accordion extends DokuWiki_Syntax_Plugin
34*5f891b7eSNickeau{
35*5f891b7eSNickeau
36*5f891b7eSNickeau
37*5f891b7eSNickeau    const TAG = 'accordion';
38*5f891b7eSNickeau
39*5f891b7eSNickeau    /**
40*5f891b7eSNickeau     * @var int a counter to give an id to the accordion card
41*5f891b7eSNickeau     */
42*5f891b7eSNickeau    private $accordionCounter = 0;
43*5f891b7eSNickeau
44*5f891b7eSNickeau    /**
45*5f891b7eSNickeau     * Syntax Type.
46*5f891b7eSNickeau     *
47*5f891b7eSNickeau     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
48*5f891b7eSNickeau     * @see DokuWiki_Syntax_Plugin::getType()
49*5f891b7eSNickeau     */
50*5f891b7eSNickeau    function getType()
51*5f891b7eSNickeau    {
52*5f891b7eSNickeau        return 'container';
53*5f891b7eSNickeau    }
54*5f891b7eSNickeau
55*5f891b7eSNickeau    /**
56*5f891b7eSNickeau     * @return array
57*5f891b7eSNickeau     * Allow which kind of plugin inside
58*5f891b7eSNickeau     *
59*5f891b7eSNickeau     * One of array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs')
60*5f891b7eSNickeau     * 'baseonly' will run only in the base mode
61*5f891b7eSNickeau     * because we manage self the content and we call self the parser
62*5f891b7eSNickeau     *
63*5f891b7eSNickeau     * Return an array of one or more of the mode types {@link $PARSER_MODES} in Parser.php
64*5f891b7eSNickeau     */
65*5f891b7eSNickeau    public function getAllowedTypes()
66*5f891b7eSNickeau    {
67*5f891b7eSNickeau        return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
68*5f891b7eSNickeau    }
69*5f891b7eSNickeau
70*5f891b7eSNickeau    public function accepts($mode)
71*5f891b7eSNickeau    {
72*5f891b7eSNickeau        /**
73*5f891b7eSNickeau         * header mode is disable to take over
74*5f891b7eSNickeau         * and replace it with {@link syntax_plugin_combo_title}
75*5f891b7eSNickeau         */
76*5f891b7eSNickeau        if ($mode == "header") {
77*5f891b7eSNickeau            return false;
78*5f891b7eSNickeau        }
79*5f891b7eSNickeau        /**
80*5f891b7eSNickeau         * If preformatted is disable, we does not accept it
81*5f891b7eSNickeau         */
82*5f891b7eSNickeau        if (!$this->getConf(syntax_plugin_combo_preformatted::CONF_PREFORMATTED_ENABLE)) {
83*5f891b7eSNickeau            return PluginUtility::disablePreformatted($mode);
84*5f891b7eSNickeau        } else {
85*5f891b7eSNickeau            return true;
86*5f891b7eSNickeau        }
87*5f891b7eSNickeau    }
88*5f891b7eSNickeau
89*5f891b7eSNickeau    /**
90*5f891b7eSNickeau     * How Dokuwiki will add P element
91*5f891b7eSNickeau     *
92*5f891b7eSNickeau     * * 'normal' - The plugin can be used inside paragraphs
93*5f891b7eSNickeau     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
94*5f891b7eSNickeau     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
95*5f891b7eSNickeau     *
96*5f891b7eSNickeau     * @see DokuWiki_Syntax_Plugin::getPType()
97*5f891b7eSNickeau     */
98*5f891b7eSNickeau    function getPType()
99*5f891b7eSNickeau    {
100*5f891b7eSNickeau        return 'block';
101*5f891b7eSNickeau    }
102*5f891b7eSNickeau
103*5f891b7eSNickeau    /**
104*5f891b7eSNickeau     * @see Doku_Parser_Mode::getSort()
105*5f891b7eSNickeau     * Higher number than the teaser-columns
106*5f891b7eSNickeau     * because the mode with the lowest sort number will win out
107*5f891b7eSNickeau     */
108*5f891b7eSNickeau    function getSort()
109*5f891b7eSNickeau    {
110*5f891b7eSNickeau        return 200;
111*5f891b7eSNickeau    }
112*5f891b7eSNickeau
113*5f891b7eSNickeau    /**
114*5f891b7eSNickeau     * Create a pattern that will called this plugin
115*5f891b7eSNickeau     *
116*5f891b7eSNickeau     * @param string $mode
117*5f891b7eSNickeau     * @see Doku_Parser_Mode::connectTo()
118*5f891b7eSNickeau     */
119*5f891b7eSNickeau    function connectTo($mode)
120*5f891b7eSNickeau    {
121*5f891b7eSNickeau
122*5f891b7eSNickeau
123*5f891b7eSNickeau        $pattern = PluginUtility::getContainerTagPattern(self::TAG);
124*5f891b7eSNickeau        $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeForComponent($this->getPluginComponent()));
125*5f891b7eSNickeau
126*5f891b7eSNickeau
127*5f891b7eSNickeau    }
128*5f891b7eSNickeau
129*5f891b7eSNickeau    public function postConnect()
130*5f891b7eSNickeau    {
131*5f891b7eSNickeau
132*5f891b7eSNickeau
133*5f891b7eSNickeau        $this->Lexer->addExitPattern('</' . self::TAG . '>', PluginUtility::getModeForComponent($this->getPluginComponent()));
134*5f891b7eSNickeau
135*5f891b7eSNickeau
136*5f891b7eSNickeau    }
137*5f891b7eSNickeau
138*5f891b7eSNickeau    /**
139*5f891b7eSNickeau     *
140*5f891b7eSNickeau     * The handle function goal is to parse the matched syntax through the pattern function
141*5f891b7eSNickeau     * and to return the result for use in the renderer
142*5f891b7eSNickeau     * This result is always cached until the page is modified.
143*5f891b7eSNickeau     * @param string $match
144*5f891b7eSNickeau     * @param int $state
145*5f891b7eSNickeau     * @param int $pos
146*5f891b7eSNickeau     * @param Doku_Handler $handler
147*5f891b7eSNickeau     * @return array|bool
148*5f891b7eSNickeau     * @see DokuWiki_Syntax_Plugin::handle()
149*5f891b7eSNickeau     *
150*5f891b7eSNickeau     */
151*5f891b7eSNickeau    function handle($match, $state, $pos, Doku_Handler $handler)
152*5f891b7eSNickeau    {
153*5f891b7eSNickeau
154*5f891b7eSNickeau        switch ($state) {
155*5f891b7eSNickeau
156*5f891b7eSNickeau            case DOKU_LEXER_ENTER:
157*5f891b7eSNickeau
158*5f891b7eSNickeau                $this->accordionCounter++;
159*5f891b7eSNickeau                $attributes = PluginUtility::getTagAttributes($match);
160*5f891b7eSNickeau
161*5f891b7eSNickeau                // Attributes has at
162*5f891b7eSNickeau                // https://getbootstrap.com/docs/4.6/components/collapse/#accordion-example
163*5f891b7eSNickeau                PluginUtility::addClass2Attributes("accordion", $attributes);
164*5f891b7eSNickeau                if (!in_array("id", $attributes)) {
165*5f891b7eSNickeau                    $attributes["id"] = self::TAG . $this->accordionCounter;
166*5f891b7eSNickeau                }
167*5f891b7eSNickeau
168*5f891b7eSNickeau                return array(
169*5f891b7eSNickeau                    PluginUtility::STATE => $state,
170*5f891b7eSNickeau                    PluginUtility::ATTRIBUTES => $attributes
171*5f891b7eSNickeau                );
172*5f891b7eSNickeau
173*5f891b7eSNickeau            case DOKU_LEXER_UNMATCHED :
174*5f891b7eSNickeau
175*5f891b7eSNickeau                $html = PluginUtility::escape($match);
176*5f891b7eSNickeau
177*5f891b7eSNickeau                return array(
178*5f891b7eSNickeau                    PluginUtility::STATE => $state,
179*5f891b7eSNickeau                    PluginUtility::PAYLOAD => $html
180*5f891b7eSNickeau                );
181*5f891b7eSNickeau
182*5f891b7eSNickeau
183*5f891b7eSNickeau            case DOKU_LEXER_EXIT :
184*5f891b7eSNickeau
185*5f891b7eSNickeau                return array(
186*5f891b7eSNickeau                    PluginUtility::STATE => $state
187*5f891b7eSNickeau                );
188*5f891b7eSNickeau
189*5f891b7eSNickeau
190*5f891b7eSNickeau        }
191*5f891b7eSNickeau
192*5f891b7eSNickeau        return array();
193*5f891b7eSNickeau
194*5f891b7eSNickeau    }
195*5f891b7eSNickeau
196*5f891b7eSNickeau    /**
197*5f891b7eSNickeau     * Render the output
198*5f891b7eSNickeau     * @param string $format
199*5f891b7eSNickeau     * @param Doku_Renderer $renderer
200*5f891b7eSNickeau     * @param array $data - what the function handle() return'ed
201*5f891b7eSNickeau     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
202*5f891b7eSNickeau     * @see DokuWiki_Syntax_Plugin::render()
203*5f891b7eSNickeau     *
204*5f891b7eSNickeau     *
205*5f891b7eSNickeau     */
206*5f891b7eSNickeau    function render($format, Doku_Renderer $renderer, $data)
207*5f891b7eSNickeau    {
208*5f891b7eSNickeau
209*5f891b7eSNickeau        if ($format == 'xhtml') {
210*5f891b7eSNickeau
211*5f891b7eSNickeau            /** @var Doku_Renderer_xhtml $renderer */
212*5f891b7eSNickeau            $state = $data[PluginUtility::STATE];
213*5f891b7eSNickeau            switch ($state) {
214*5f891b7eSNickeau                case DOKU_LEXER_ENTER:
215*5f891b7eSNickeau                    $attributes = $data[PluginUtility::ATTRIBUTES];
216*5f891b7eSNickeau                    $renderer->doc .= '<div ' . PluginUtility::array2HTMLAttributes($attributes) . '>' . DOKU_LF;
217*5f891b7eSNickeau                    break;
218*5f891b7eSNickeau                case DOKU_LEXER_UNMATCHED:
219*5f891b7eSNickeau                    $renderer->doc .= PluginUtility::escape($data[PluginUtility::PAYLOAD]);
220*5f891b7eSNickeau                    break;
221*5f891b7eSNickeau                case DOKU_LEXER_EXIT:
222*5f891b7eSNickeau                    $renderer->doc .= '</div>' . DOKU_LF;
223*5f891b7eSNickeau                    break;
224*5f891b7eSNickeau            }
225*5f891b7eSNickeau
226*5f891b7eSNickeau
227*5f891b7eSNickeau            return true;
228*5f891b7eSNickeau        }
229*5f891b7eSNickeau        return false;
230*5f891b7eSNickeau    }
231*5f891b7eSNickeau
232*5f891b7eSNickeau
233*5f891b7eSNickeau}
234