Skip to content

nested declarations in a widget's parameters break the widget in wysiwyg editor #26492

Open
@ioweb-gr

Description

@ioweb-gr

Preconditions (*)

  1. 2.3.3

Steps to reproduce (*)

  1. Create a module which creates a custom widget.
  2. Add a parameter for an image chooser like this
<parameter name="photo" xsi:type="block" visible="true" sort_order="10">
    <label translate="true">Photo</label>
    <description translate="true">Contact photo</description>
    <block class="Vendor\Widget\Block\Adminhtml\Widget\ImageChooser">
        <data>
            <item name="button" xsi:type="array">
                <item name="open" xsi:type="string">Choose Image...</item>
            </item>
        </data>
    </block>
</parameter>
  1. The image chooser class
use Magento\Framework\Data\Form\Element\AbstractElement as Element;
use Magento\Backend\Block\Template\Context as TemplateContext;
use Magento\Framework\Data\Form\Element\Factory as FormElementFactory;
use Magento\Backend\Block\Template;
class ImageChooser extends Template
{
    /**
     * @var \Magento\Framework\Data\Form\Element\Factory
     */
    protected $elementFactory;
    /**
     * @param TemplateContext $context
     * @param FormElementFactory $elementFactory
     * @param array $data
     */
    public function __construct(
        TemplateContext $context,
        FormElementFactory $elementFactory,
        $data = []
    ) {
        $this->elementFactory = $elementFactory;
        parent::__construct($context, $data);
    }
    /**
     * Prepare chooser element HTML
     *
     * @param Element $element
     * @return Element
     */
    public function prepareElementHtml(Element $element)
    {
        $config = $this->_getData('config');
        $sourceUrl = $this->getUrl('cms/wysiwyg_images/index',
            ['target_element_id' => $element->getId(), 'type' => 'file']);
        /** @var \Magento\Backend\Block\Widget\Button $chooser */
        $chooser = $this->getLayout()->createBlock('Magento\Backend\Block\Widget\Button')
            ->setType('button')
            ->setClass('btn-chooser')
            ->setLabel($config['button']['open'])
            ->setOnClick('MediabrowserUtility.openDialog(\''. $sourceUrl .'\')')
            ->setDisabled($element->getReadonly());
        /** @var \Magento\Framework\Data\Form\Element\Text $input */
        $input = $this->elementFactory->create("text", ['data' => $element->getData()]);
        $input->setId($element->getId());
        $input->setForm($element->getForm());
        $input->setClass("widget-option input-text admin__control-text");
        if ($element->getRequired()) {
            $input->addClass('required-entry');
        }
        $element->setData('after_element_html', $input->getElementHtml() . $chooser->toHtml());
        return $element;
    }
}
  1. You end up with a string like this after trying to import the image
    {{widget type="Vendor\Widget\Block\TwinProductSlider" photo="https://example.com/admin/cms/wysiwyg/directive/___directive/e3ttZWRpYSB1cmw9InRlc3QvU2NyZWVuc2hvdF80LnBuZyJ9fQ,,/key/b2c5cfcfabd77525750beb97f9652a4690c523684f849a0a10b810baf9f2b39c/"}}

  2. When you save the cms page for example that contains the widget you end up with this
    {{widget type="Vendor\Widget\Block\TwinProductSlider" photo="{{media url="test/Screenshot_4.png"}}"}}

  3. This ends up breaking the widget because of nesting. In the backend it looks like this
    image

Expected result (*)

  1. The widget does not break

Actual result (*)

  1. The widget is broken
    image

In order to work around the issue we have to use static urls for media images or create a plugin to change the behaviour so that the parameter value is modified on save.

I've tracked lots of issues in various tutorials and gists and they all have to end up with some workaround like this to make it work. e.g.
https://gist.github.com/cedricblondeau/6174911fb4bba6cb4943#gistcomment-2056776

In my opinion this shouldn't happen out of the box and looks like a bug.
Also:
is there no predefined image upload block for widgets? Why so?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area: UI FrameworkCDIssue recommended for the contribution dayComponent: Framework/WysiwygComponent: WidgetIssue: Clear DescriptionGate 2 Passed. Manual verification of the issue description passedIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedIssue: Format is validGate 1 Passed. Automatic verification of issue format passedIssue: Ready for WorkGate 4. Acknowledged. Issue is added to backlog and ready for developmentPriority: P2A defect with this priority could have functionality issues which are not to expectations.Progress: ready for devReported on 2.3.3Indicates original Magento version for the Issue report.Reproduced on 2.4.xThe issue has been reproduced on latest 2.4-develop branchSeverity: S2Major restrictions or short-term circumventions are required until a fix is available.Triage: Dev.ExperienceIssue related to Developer Experience and needs help with Triage to Confirm or Reject it

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions