I created a new Block that renders a button to upload an image via Magento's Mediabrowserutility. This Module is also used for uploading images to a CMS Page. The Block is used to add Image Uploads to a Widget.

The Block Code is the following:

 * 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')
                    ->setOnClick('MediabrowserUtility.openDialog(\'' . $sourceUrl . '\', 0, 0, "MediaBrowser", {})')

    /** @var \Magento\Framework\Data\Form\Element\Text $input */
    $input = $this->_elementFactory->create("text", ['data' => $element->getData()]);
    $input->setClass("widget-option input-text admin__control-text");
    if ($element->getRequired()) {

    $element->setData('after_element_html', $input->getElementHtml()
        . $chooser->toHtml() . "<script>require(['mage/adminhtml/browser']);</script>");

    return $element;

As you see, the onClick Event triggers the MediaBrowser. I am able to use the MediaBrowser as expected, but as soon as I save the whole widget, the URLs from the Image refer to an image that is not reachable in the frontend, because an admin session is required.

This is what the URLs look like:


You need to create a plugin to the class Magento\Widget\Model\Widget. See my original post & answer here

The first thing you need to do is create a new plugin (interceptor) under [COMPANY]/[MODULE]/etc/di.xml

<?xml version="1.0" encoding="UTF-8" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Widget\Model\Widget">
        <plugin name="test1" type="[COMPANY]\[MODULE]\Model\Widget" sortOrder="1" disabled="false"/>

Then create the interceptor logic, you need to use the before method, this way you can change the parameters being passed to \Magento\Widget\Model\Widget, getWidgetDeclaration so something like this.

namespace [COMPANY]\[MODULE]\Model;

use \Magento\Widget\Model\Widget as BaseWidget;

class Widget
    public function beforeGetWidgetDeclaration(BaseWidget $subject, $type, $params = [], $asIs = true)
        // I rather do a check for a specific parameters
        if(key_exists("widget_image_chooser", $params)) {

            $url = $params["widget_image_chooser"];
            if(strpos($url,'/directive/___directive/') !== false) {

                $parts = explode('/', $url);
                $key   = array_search("___directive", $parts);
                if($key !== false) {

                    $url = $parts[$key+1];
                    $url = base64_decode(strtr($url, '-_,', '+/='));

                    $parts = explode('"', $url);
                    $key   = array_search("{{media url=", $parts);
                    $url   = $parts[$key+1];

                    $params["widget_image_chooser"] = $url;

        return array($type, $params, $asIs);
|improve this answer|||||
  • 1
    Finally :D That is what I needed :) Thank you! – David Lambauer Nov 22 '17 at 17:09

I've been trying to get this to work without much luck. I'm preparing my image in Block\Widget\BannerWidget.php. The field returns public function getImage() { $url = $this->getData('banner_image'); return $url; }

|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.