Description
Preconditions (*)
- 2.3.3
Steps to reproduce (*)
- Create a module which creates a custom widget.
- 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>
- 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;
}
}
-
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/"}}
-
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"}}"}}
-
This ends up breaking the widget because of nesting. In the backend it looks like this
Expected result (*)
- The widget does not break
Actual result (*)
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?