Magento2创建自定义Widget 并通过添加图片选择器插入图片

 

创建自定义Widget 并通过添加图片选择器插入图片

自定义widget

  1. 先在模块的etc 配置文件中创建widget.xml配置文件

    例如:在HomeCategoryList模块中创建widget文件位置:\Rokanthemes\HomeCategoryList\etc\widget.xml

    代码内容:

    <widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="../../../Magento/Widget/etc/widget.xsd">
        <widget id="custom_homepage_category_title" class="Rokanthemes\HomeCategoryList\Block\HomeCategoryTitle"
                is_email_compatible="true"
                placeholder_image="Magento_CatalogWidget::images/products_list.png" ttl="86400">
            <label translate="true">Custom Homepage Category Title</label>
            <description translate="true">Custom Homepage Category Title</description>
            <parameters>
                <parameter name="title" xsi:type="text" required="true" visible="true">
                    <label translate="true">Title</label>
                </parameter>
                <parameter name="short_desc" xsi:type="text" required="false" visible="true">
                    <label translate="true">Short Desc</label>
                </parameter>
            </parameters>
        </widget>
    </widgets>
    
  2. 在block中创建对应的类

    上面配置中<widget>标签中的class值为当前widget所对应的class类,所以要在对应位置创建HomeCategoryTitle.php文件

    位置为:Rokanthemes\HomeCategoryList\Block\HomeCategoryTitle 代码内容示例:

    <?php
    namespace Rokanthemes\HomeCategoryList\Block;
    class HomeCategoryTitle extends \Magento\Catalog\Block\Product\AbstractProduct implements \Magento\Widget\Block\BlockInterface
    {
        protected $httpContext;
        protected $_catalogProductVisibility;
        protected $productCollectionFactory;
        protected $sqlBuilder;
        protected $rule;
    
        protected $conditionsHelper;
    	protected $_categoryFactory;
    	protected $productFactory;
    	protected $_scopeConfig;
    
        public function __construct(
            \Magento\Catalog\Block\Product\Context $context,
            \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
            \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility,
            \Magento\Framework\App\Http\Context $httpContext,
            \Magento\Rule\Model\Condition\Sql\Builder $sqlBuilder,
            \Magento\CatalogWidget\Model\Rule $rule,
            \Magento\Widget\Helper\Conditions $conditionsHelper,
    		\Magento\Catalog\Model\CategoryFactory $categoryFactory,
            array $data = []
        ) {
            $this->productCollectionFactory = $productCollectionFactory;
            $this->_catalogProductVisibility = $catalogProductVisibility;
            $this->httpContext = $httpContext;
            $this->sqlBuilder = $sqlBuilder;
            $this->rule = $rule;
            $this->conditionsHelper = $conditionsHelper;
    		$this->_categoryFactory = $categoryFactory;
    		$this->_scopeConfig = $context->getScopeConfig();
            parent::__construct(
                $context,
                $data
            );
            $this->_isScopePrivate = true;
        }
    
        /**
         * {@inheritdoc}
         */
        protected function _construct()
        {  
            parent::_construct();
            $this->setTemplate('widget/home_category_title.phtml');
        }
    
        public function getTitle()
        {
            return $this->getData('title');
        }
    
        public function getCategoryId()
        {
            $categoryIdLink = explode('/',$this->getData('category_id'));
            return end($categoryIdLink);
        }
    
        public function getLeftBigImage(){
            return $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA).$this->getData('left_big_image');
        }
    
        public function getLeftBigImageLink(){
            return $this->getData('left_big_image_link');
        }
    
        public function getBaseUrl()
        {
            return $this->_storeManager->getStore()->getBaseUrl();
        }
    
    }
    ?>
    
  3. 创建widget对应的template文件

    在上面block创建的方法中有以下代码段:

    protected function _construct(){  
        parent::_construct();
        $this->setTemplate('widget/home_category_title.phtml');
    }
    

    其实这里就是设置widget对应的.phtml文件所以我们需要在Rokanthemes\HomeCategoryList\view\frontend\templates\widget\位置创建对应的home_category_title.phtml文件。

    代码内容:

    <div class="rokan-product-heading rokan-featured-heading">
    <h2><?php echo $block->getTitle(); ?></h2>
    <?php if ($block->getShortDescData()): ?>
        <div class="short_desc"><p><?php echo $this->getShortDescData(); ?></p></div>
    <?php endif; ?>
    </div>
    
  4. 命令行清除缓存重新生成静态

    清除缓存:

    php bin/magento cache:clean
    

    重新安装di

    php  bin/magento setup:di:compile
    

    生成静态

    php  bin/magento setup:static-content:deploy
    

自定义widget中添加图片选择器插入图片

widget.xml中添加图片选择器parameter

<parameter name="below_image" xsi:type="block" required="true" visible="true">
    <label translate="true">Below Image</label>
    <description translate="true">Select Insert photo</description>
    <block class="Rokanthemes\HomeCategoryList\Block\Adminhtml\Widget\ImageChooser">
        <data>
            <item name="button" xsi:type="array">
                <item name="open" xsi:type="string">Choose Image...</item>
            </item>
        </data>
    </block>
</parameter>

模块block中添加ImageChooser.php文件

文件位置:Rokanthemes\HomeCategoryList\Block\Adminhtml\Widget\

代码:

<?php

namespace Rokanthemes\HomeCategoryList\Block\Adminhtml\Widget;

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', null, null, '".$this->escapeQuote(__('Choose Image...'),true)."', (opt = new Object(), opt.closed = false, opt) )" )
                ->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;
    }
}

创建拦截器对插入图片地址进行处理

因为是在widget中插入图片,默认会插入带有'{{','}}'的引用方式,会与widget的引用造成冲突从而使图片无法正常显示。所以需要在插入动作之后对图片地址进行处理

创建一个新的插件(拦截器) Rokanthemes/HomeCategoryList/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <type name="Magento\Widget\Model\Widget">
        <plugin name="insert_picture_before" type="Rokanthemes\HomeCategoryList\Model\Widget" sortOrder="1" disabled="false"/>
    </type>
</config>

然后创建拦截器逻辑,需要使用before方法,这样就可以改变传递给\Magento\Widget\Model\Widget方法getWidgetDeclaration的参数,getWidgetDeclaration

文件位置:Rokanthemes\HomeCategoryList\Model\

文件名:Widget.php

代码内容:

<?php
/**
 * Created by PhpStorm.
 * User: Hankin.Peng
 * Date: 2018/7/20
 * Time: 16:03
 */
namespace Rokanthemes\HomeCategoryList\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
        $str='Rokanthemes\HomeCategoryList\Block\HomeCategory';
        $pictureStr='Picture';
        if(strstr($type,$str) && stristr($type,$pictureStr)) {
            foreach ($params as $paramKey => $value) {
                $url = $params[$paramKey];
                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[$paramKey] = $url;
                    }
                }
            }
        }
        return array($type, $params, $asIs);
    }
}

223916_bL9y_2663968.jpg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值