0

I have been trying to have some blocks with collapsible content, but to put them in cms blocks so the text can be maintained by a normal human

I have found, thanks to previous stack discussions, that the syntax in the magento documentation needs extra quoting for it to save properly. It works. BUT IT ONLY WORKS FOR ONE SAVE, THEN IT BREAKS

<div data-mage-init='{"accordion":{"openedState": "active", "collapsible": "true", "active": "1", "multipleCollapsible": "false"}}'>
<div data-role="collapsible">
    <div data-role="trigger">
        Title 1
    </div>
</div>
<div data-role="content">
    <p>
        Content 1 bla bla bla.
    </p>
</div>
<div data-role="collapsible">
    <div data-role="trigger">
        Title 2
    </div>
</div>
<div data-role="content">
    <p>
        Content 2 bla bla bla.
    </p>
</div>

If I put this in and save works fine on the front end

The problem I have is that the next time I open the editor, under the scenes the html has been changed to

<div data-mage-init="{"accordion":{"openedState": "active", "collapsible": "true", "active": "1", "multipleCollapsible": "false"}}">

and that, on saved, gets garbled to

<div data-mage-init="{">

which obviously will not work to trigger an accordion and will also break other elements which rely on data-mage-init and RequireJS

Note the same happens on a CMS page.

I have tried putting it as

<div data-mage-init="{&quot;accordion&quot;:{&quot;openedState&quot;: &quot;active&quot;, &quot;collapsible&quot;: &quot;true&quot;, &quot;active&quot;: &quot;1&quot;, &quot;multipleCollapsible&quot;: &quot;true&quot;}}">

and that, saved, also work - but on the next opening it too gets turned into

<div data-mage-init="{"accordion":{"openedState": "active", "collapsible": "true", "active": "1", "multipleCollapsible": "false"}}">

and breaks again.

So on an edit one must show source and fix that line, before saving, every time, else the block breaks.

Has anyone figured out how data-mage-init can be formatted to not break in a cms block?

putting the <div data-mage-init=...> call in the "parent" content where the cms block is put in as a widget didn't work either - though a wrapper block calling that block did work. But that is a ridiculously unmaintainable option - as is creating a whole new widget and content editing section just so I can add content that uses a built in layout option!

I have considered creating a custom block template that would have the accordion code but then I lose the ability to set what tabs are expanded on open, or any other flexibility.

Is this truly impossible or can these data-mage entries work in cms content? How can i put a maintainable bit of accordion content in my pages?

  • you can see it happen live if you go back and forth between code view and editor view, it is eerie – iphigenie May 6 at 15:18
  • it is sad that other combinations of single quote/double quote are maintained, but the only one valid for passing json values is the one that is messed up – iphigenie May 13 at 13:20
  • there's a magento bug about it, as the same pattern also breaks some variables and links in wysiwyg – iphigenie Jun 4 at 15:00
0

you can use x-magento-init instead of using data-mage-init.

change your code with below code.

<div id="myaccordian">
<div data-role="collapsible">
    <div data-role="trigger">
        Title 1
    </div>
</div>
<div data-role="content">
    <p>
        Content 1 bla bla bla.
    </p>
</div>
<div data-role="collapsible">
    <div data-role="trigger">
        Title 2
    </div>
</div>
<div data-role="content">
    <p>
        Content 2 bla bla bla.
    </p>
</div>
<script type="text/x-magento-init">
{
    "#myaccordian": {
    "accordion": {
            "openedState": "active",
            "collapsible": "true",
            "active": "1",
            "multipleCollapsible": "false"
        }
    }
}
</script>

Note: you are using tinyMCE - 3 because script tag is not allowed in tinyMCE4.

to change editor to tinymce3 you need to go to Admin > store configurations > general > content management and then you can see to choose editor.

hope this will work for you.

Thank you,

Nirav Patel

| improve this answer | |
  • I'll have a try on a debug site - thanks! On M1 I found a way to override the tinymce config so it allowed some tags I wanted to use so I hope there might be a way to "allow" tags like script or make it "ignore" data-mage-init instead of eating it – iphigenie May 6 at 15:16
  • thanks for pointing me towards this option, in the end i created a template and a widget to tag this javascript on – iphigenie Jun 4 at 11:04
0

Thanks to Nirav's pointers that I should switch to the script, I decided to try to "push" the bit that wysiwyg editor breaks out to a widget this is very primitive but it makes it easier to let others edit content without it breaking on save.

I can create blocks with just the content and people can edit those blocks. Then in the page or extension i embed the block via my widget - with some parameters to allow some tweaking - rather than a plain block. It's one extra step but only once, not every time.

I have a module Alpine_AlpineCustom for small tweaks like this one - use your own name!

Widget Class - a copy of Block widget that does nothing more (but might, one day) - straight empty copy of it

declare(strict_types=1);
namespace Alpine\AlpineCustom\Block\Widget;

use Magento\Framework\DataObject\IdentityInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Cms\Model\Block as CmsBlock;
use Magento\Widget\Block\BlockInterface;

class Block extends   \Magento\Cms\Block\Widget\Block implements BlockInterface, IdentityInterface
{

}

Widget definition to add some parameters for the block, I didnt want to have to redo all my cms blocks so allowed myself to set the selectors to match on, and set which are opened up front. Adapt to your own.

 <widget id="alpine_accordion_block" class="Alpine\AlpineCustom\Block\Widget\Block"
            placeholder_image="Magento_Cms::images/widget_block.png" is_email_compatible="false" ttl="86400">
        <label translate="true">Alpine Accordion</label>
        <description>Block with added wrapper for accordion</description>
        <parameters>
            <parameter name="block_id" xsi:type="block" visible="true" required="true" sort_order="20">
                <label translate="true">Block</label>
                <block class="Magento\Cms\Block\Adminhtml\Block\Widget\Chooser">
                    <data>
                        <item name="button" xsi:type="array">
                            <item name="open" xsi:type="string" translate="true">Select Block...</item>
                        </item>
                    </data>
                </block>
            </parameter>        
            <parameter name="tabToOpen" xsi:type="text" required="false"><label translate="true">tab to open</label>
            <description>numbers separated by space, eg:0 4</description><value>0</value></parameter>  
            <parameter name="titleTag" xsi:type="text" required="false"><label translate="true">Title tag</label>
            <description>dont change unless you mean it</description><value>h2</value></parameter>  
            <parameter name="triggerTag" xsi:type="text" required="false"><label translate="true">Trigger tag</label>
            <description>dont change unless you mean it</description><value>h2</value></parameter>  
            <parameter name="contentTag" xsi:type="text" required="false"><label translate="true">Content tag</label>
            <description>dont change unless you mean it</description><value>.alpinesection</value></parameter>  
            <parameter name="template" xsi:type="select" visible="true" required="true" sort_order="10">
                <label translate="true">Template for block</label>
                <options>
                   <option name="block_mageinit" value="Alpine_AlpineCustom::cms/block_mageinit.phtml" selected="true">
                        <label translate="true">Default block</label>
                    </option>
                </options>
            </parameter>
        </parameters>
    </widget>

Block template to display - basic block:

<?php
/* @var $block \Magento\Cms\Block\Widget\Block */
?>
<div class="widget block block-static-block alpine_accordion_block" id="block<?php echo $this->getBlockId();?>">

 <?= /* @noEscape */ $block->getText() ?>

 </div>

  <script type="text/x-magento-init">
  {
   ".alpine_accordion_block": {
        "accordion": {
        "collapsibleElement":"<?php echo $block->getData('titleTag');?>",
        "header":"<?php echo $block->getData('titleTag');?>",
        "content":"<?php echo $block->getData('contentTag');?>",
        "trigger":"<?php echo $block->getData('triggerTag');?>",
        "openedState":"awake",
        "closedState":"asleep",
        "collapsible":true,
        "active":"<?php echo $block->getData('tabToOpen') ?>",
        "multipleCollapsible":true
         }
      }
  }</script>
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.