xref: /plugin/combo/ComboStrap/MasonryTag.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
1*04fd306cSNickeau<?php
2*04fd306cSNickeau
3*04fd306cSNickeaunamespace ComboStrap;
4*04fd306cSNickeau
5*04fd306cSNickeau
6*04fd306cSNickeauuse Doku_Handler;
7*04fd306cSNickeauuse Doku_Renderer;
8*04fd306cSNickeau
9*04fd306cSNickeau
10*04fd306cSNickeau/**
11*04fd306cSNickeau *
12*04fd306cSNickeau * TODO: when level 3 of grid
13*04fd306cSNickeau *   https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Masonry_Layout
14*04fd306cSNickeau *
15*04fd306cSNickeau */
16*04fd306cSNickeauclass MasonryTag
17*04fd306cSNickeau{
18*04fd306cSNickeau    public const TEASER_COLUMNS_TAG = 'teaser-columns';
19*04fd306cSNickeau    /**
20*04fd306cSNickeau     * The Tag constant should be the exact same last name of the class
21*04fd306cSNickeau     * This is how we recognize a tag in the {@link \ComboStrap\CallStack}
22*04fd306cSNickeau     */
23*04fd306cSNickeau    public const MASONRY_TAG = "masonry";
24*04fd306cSNickeau    public const LOGICAL_TAG = "masonry";
25*04fd306cSNickeau    /**
26*04fd306cSNickeau     * The syntax tags
27*04fd306cSNickeau     */
28*04fd306cSNickeau    public const CARD_COLUMNS_TAG = "card-columns";
29*04fd306cSNickeau    /**
30*04fd306cSNickeau     * Same as commercial
31*04fd306cSNickeau     * https://isotope.metafizzy.co/
32*04fd306cSNickeau     *
33*04fd306cSNickeau     */
34*04fd306cSNickeau    public const MASONRY_SCRIPT_ID = "masonry";
35*04fd306cSNickeau
36*04fd306cSNickeau
37*04fd306cSNickeau    /**
38*04fd306cSNickeau     * In Bootstrap5, to support card-columns, we need masonry javascript and
39*04fd306cSNickeau     * a column
40*04fd306cSNickeau     * We close it as seen here:
41*04fd306cSNickeau     * https://getbootstrap.com/docs/5.0/examples/masonry/
42*04fd306cSNickeau     *
43*04fd306cSNickeau     * The column is open with the function {@link MasonryTag::addColIfBootstrap5AndCardColumns()}
44*04fd306cSNickeau     * @param Doku_Renderer $renderer
45*04fd306cSNickeau     * @param $context
46*04fd306cSNickeau     */
47*04fd306cSNickeau    public static function endColIfBootstrap5AnCardColumns(Doku_Renderer $renderer, $context)
48*04fd306cSNickeau    {
49*04fd306cSNickeau
50*04fd306cSNickeau        /**
51*04fd306cSNickeau         * Bootstrap five does not include masonry
52*04fd306cSNickeau         * directly, we need to add a column
53*04fd306cSNickeau         * and we close it here
54*04fd306cSNickeau         */
55*04fd306cSNickeau        $bootstrapVersion = Bootstrap::getBootStrapMajorVersion();
56*04fd306cSNickeau        if ($bootstrapVersion == Bootstrap::BootStrapFiveMajorVersion) {
57*04fd306cSNickeau            $renderer->doc .= '</div>';
58*04fd306cSNickeau        }
59*04fd306cSNickeau
60*04fd306cSNickeau    }
61*04fd306cSNickeau
62*04fd306cSNickeau    public static function getSyntaxTags(): array
63*04fd306cSNickeau    {
64*04fd306cSNickeau        return array(self::MASONRY_TAG, self::CARD_COLUMNS_TAG, self::TEASER_COLUMNS_TAG);
65*04fd306cSNickeau    }
66*04fd306cSNickeau
67*04fd306cSNickeau    /**
68*04fd306cSNickeau     * @param $renderer
69*04fd306cSNickeau     * @param $context Doku_Renderer
70*04fd306cSNickeau     *
71*04fd306cSNickeau     * Bootstrap five does not include masonry
72*04fd306cSNickeau     * directly, we need to add a column around the children {@link syntax_plugin_combo_card} and
73*04fd306cSNickeau     * {@link BlockquoteTag}
74*04fd306cSNickeau     * https://getbootstrap.com/docs/5.0/examples/masonry/
75*04fd306cSNickeau     *
76*04fd306cSNickeau     * The column is open with the function {@link syntax_plugin_combo_masonry::endColIfBootstrap5AndCardColumns()}
77*04fd306cSNickeau     *
78*04fd306cSNickeau     * TODO: do it programmatically by adding call with {@link \ComboStrap\CallStack}
79*04fd306cSNickeau     */
80*04fd306cSNickeau    public static function addColIfBootstrap5AndCardColumns(&$renderer, $context)
81*04fd306cSNickeau    {
82*04fd306cSNickeau        $bootstrapVersion = Bootstrap::getBootStrapMajorVersion();
83*04fd306cSNickeau        if ($bootstrapVersion == Bootstrap::BootStrapFiveMajorVersion && $context == MasonryTag::MASONRY_TAG) {
84*04fd306cSNickeau            $renderer->doc .= '<div class="col-sm-6 col-lg-4 mb-4">';
85*04fd306cSNickeau        }
86*04fd306cSNickeau    }
87*04fd306cSNickeau
88*04fd306cSNickeau    public static function handleExit(Doku_Handler $handler)
89*04fd306cSNickeau    {
90*04fd306cSNickeau        /**
91*04fd306cSNickeau         * When the masonry is used in an iterator, the direct
92*04fd306cSNickeau         * context is lost
93*04fd306cSNickeau         */
94*04fd306cSNickeau        $callStack = CallStack::createFromHandler($handler);
95*04fd306cSNickeau        $callStack->moveToPreviousCorrespondingOpeningCall();
96*04fd306cSNickeau        while ($actualCall = $callStack->next()) {
97*04fd306cSNickeau            if (
98*04fd306cSNickeau                in_array($actualCall->getTagName(), [CardTag::CARD_TAG, BlockquoteTag::TAG])
99*04fd306cSNickeau                && in_array($actualCall->getState(), [DOKU_LEXER_ENTER, DOKU_LEXER_EXIT])
100*04fd306cSNickeau            ) {
101*04fd306cSNickeau                $actualCall->setContext(MasonryTag::MASONRY_TAG);
102*04fd306cSNickeau            }
103*04fd306cSNickeau        }
104*04fd306cSNickeau
105*04fd306cSNickeau    }
106*04fd306cSNickeau
107*04fd306cSNickeau    public static function renderEnterTag(): string
108*04fd306cSNickeau    {
109*04fd306cSNickeau        $bootstrapVersion = Bootstrap::getBootStrapMajorVersion();
110*04fd306cSNickeau        switch ($bootstrapVersion) {
111*04fd306cSNickeau            case 5:
112*04fd306cSNickeau                // No support for 5, we use Bs with their example
113*04fd306cSNickeau                // https://getbootstrap.com/docs/5.0/examples/masonry/
114*04fd306cSNickeau                // https://masonry.desandro.com/layout.html#responsive-layouts
115*04fd306cSNickeau                // https://masonry.desandro.com/extras.html#bootstrap
116*04fd306cSNickeau                // https://masonry.desandro.com/#initialize-with-vanilla-javascript
117*04fd306cSNickeau                PluginUtility::getSnippetManager()->attachRemoteJavascriptLibrary(
118*04fd306cSNickeau                    MasonryTag::MASONRY_SCRIPT_ID,
119*04fd306cSNickeau                    "https://cdn.jsdelivr.net/npm/masonry-layout@4.2.2/dist/masonry.pkgd.min.js",
120*04fd306cSNickeau                    "sha384-GNFwBvfVxBkLMJpYMOABq3c+d3KnQxudP/mGPkzpZSTYykLBNsZEnG2D9G/X/+7D"
121*04fd306cSNickeau                );
122*04fd306cSNickeau                PluginUtility::getSnippetManager()->attachJavascriptFromComponentId(MasonryTag::MASONRY_SCRIPT_ID);
123*04fd306cSNickeau                $masonryClass = MasonryTag::MASONRY_SCRIPT_ID;
124*04fd306cSNickeau                return "<div class=\"row $masonryClass\">";
125*04fd306cSNickeau            default:
126*04fd306cSNickeau                return '<div class="card-columns">' ;
127*04fd306cSNickeau        }
128*04fd306cSNickeau    }
129*04fd306cSNickeau
130*04fd306cSNickeau    public static function renderExitHtml(): string
131*04fd306cSNickeau    {
132*04fd306cSNickeau        return '</div>';
133*04fd306cSNickeau    }
134*04fd306cSNickeau}
135*04fd306cSNickeau
136