4

How to add image upload field to a CMS page and show this on top of my CMS page as Hero image like shown below?

Maybe there are simple solutions/tutorials, but I can't find right one.

Hero image example

  • You can upload image in the CMS and Block and than call this block on the CMS page which you want. – mageDev0688 Mar 31 '17 at 11:48
9

First you have to create your own module to override the save action and dataProvider for cms page. If you don't know how to create module Please refer this link http://inchoo.net/magento-2/how-to-create-a-basic-module-in-magento-2/.

After creating a module, follow the following steps:

Step 1. Add column for custom image on cms_page table

Create InstallSchema.php under [Vendor][Module]\Setup. Your file location will be [Vendor][Module]\Setup\InstallSchema.php

namespace [Vendor]\[Module]\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\DB\Ddl\Table;

class InstallSchema implements InstallSchemaInterface
{
    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $installer = $setup;
        $installer->startSetup();
        $connection = $installer->getConnection();

        $connection->addColumn('cms_page','your_image_field_name',['type' =>\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,'comment' => 'Your Image Field Name']);
        $installer->endSetup();
    }
}

If your module is already activated, please delete your module from setup_module table.

After Creating InstallSchema.php, open your terminal and hit following commands. It will add column to database table and clear caches.

php bin/magento cache:flush;
php bin/magento setup:upgrade;
php bin/magento setup:di:compile;
rm -rf var/generation/* var/di/* var/cache/* var/page_cache/* ;
rm -rf pub/static/frontend pub/static/_requirejs pub/static/adminhtml ;

Step 2. Add image field

Create cms_page_form.xml under [Vendor]/[Module]/View/adminhtml/ui_component . Your file location will be [Vendor]/[Module]/View/adminhtml/ui_component/cms_page_form.xml. Add following code.

<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="content">
        <field name="your_image_field_name">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">string</item>
                    <item name="source" xsi:type="string">category</item>
                    <item name="label" xsi:type="string" translate="true">Your image field Name</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <item name="formElement" xsi:type="string">fileUploader</item>
                    <item name="elementTmpl" xsi:type="string">ui/form/element/uploader/uploader</item>
                    <item name="required" xsi:type="boolean">false</item>
                    <item name="uploaderConfig" xsi:type="array">
                        <item name="url" xsi:type="url" path="[module]/cms_heroimage/upload"/>
                    </item>
                </item>
            </argument>
        </field>
    </fieldset>
</form>

This will generate field under content tab.

Step 3. Create Controller for upload action.

Create Upload.php on [Vendor]/[Module]/Controller/Adminhtml/Cms/Heroimage. Your file location will be [Vendor]/[Module]/Controller/Adminhtml/Cms/Heroimage/Upload.php.

Add following code.

namespace [Vendor]\[Module]\Controller\Adminhtml\Cms\Heroimage;

use Magento\Framework\Controller\ResultFactory;

class Upload extends \Magento\Backend\App\Action
{
    /**
     * Image uploader
     *
     * @var \[Vendor]\[Module]\Model\ImageUploader
     */
    protected $imageUploader;

    /**
     * @param \Magento\Backend\App\Action\Context $context
     * @param \Magento\Catalog\Model\ImageUploader $imageUploader
     */
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Catalog\Model\ImageUploader $imageUploader
    ) {
        parent::__construct($context);
        $this->imageUploader = $imageUploader;
    }


    /**
     * Upload file controller action
     *
     * @return \Magento\Framework\Controller\ResultInterface
     */
    public function execute()
    {
        try {
            $result = $this->imageUploader->saveFileToTmpDir('your_image_field_name');

            $result['cookie'] = [
                'name' => $this->_getSession()->getName(),
                'value' => $this->_getSession()->getSessionId(),
                'lifetime' => $this->_getSession()->getCookieLifetime(),
                'path' => $this->_getSession()->getCookiePath(),
                'domain' => $this->_getSession()->getCookieDomain(),
            ];
        } catch (\Exception $e) {
            $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()];
        }
        return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($result);
    }
}
?>

Step 4. Override Save action.

Create di.xml under [Vendor][Module]\etc\adminhtml. Your file location will be [Vendor][Module]\etc\adminhtml\di.xml add following line to override Save Action and DataProvider for cms page.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Cms\Controller\Adminhtml\Page\Save" type="[Vendor]\[Module]\Controller\Adminhtml\Cms\Page\Save" />
    <preference for="Magento\Cms\Model\Page\DataProvider" type="[Vendor]\[Module]\Model\Cms\Page\DataProvider" />
</config>

Step 5. Create Save.php file. Create Save.php file under [Vendor][Module]\Controller\Adminhtml\Cms\Page. Your file location will be [Vendor][Module]\Controller\Adminhtml\Cms\Page\Save.php. Add Following code.

namespace [Vendor]\[Module]\Controller\Adminhtml\Cms\Page;

use Magento\Backend\App\Action;
use Magento\Cms\Model\Page;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\Exception\LocalizedException;

class Save extends \Magento\Cms\Controller\Adminhtml\Page\Save
{
    /**
     * Authorization level of a basic admin session
     *
     * @see _isAllowed()
     */
    const ADMIN_RESOURCE = 'Magento_Cms::save';

    /**
     * @var PostDataProcessor
     */
    protected $dataProcessor;

    /**
     * @var DataPersistorInterface
     */
    protected $dataPersistor;


    /**
     * Save action
     *
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @return \Magento\Framework\Controller\ResultInterface
     */
    public function execute()
    {
        $data = $this->getRequest()->getPostValue();


        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
        $resultRedirect = $this->resultRedirectFactory->create();
        if ($data) {
            $data = $this->dataProcessor->filter($data);
            if (isset($data['is_active']) && $data['is_active'] === 'true') {
                $data['is_active'] = Page::STATUS_ENABLED;
            }
            if (empty($data['page_id'])) {
                $data['page_id'] = null;
            }

            /** @var \Magento\Cms\Model\Page $model */
            $model = $this->_objectManager->create('Magento\Cms\Model\Page');

            $id = $this->getRequest()->getParam('page_id');
            if ($id) {
                $model->load($id);
            }

            // Add custom image field to data
            if(isset($data['your_image_field_name']) && is_array($data['your_image_field_name'])){
                $data['your_image_field_name']=$data['your_image_field_name'][0]['name'];
            }


            $model->setData($data);

            $this->_eventManager->dispatch(
                'cms_page_prepare_save',
                ['page' => $model, 'request' => $this->getRequest()]
            );

            if (!$this->dataProcessor->validate($data)) {
                return $resultRedirect->setPath('*/*/edit', ['page_id' => $model->getId(), '_current' => true]);
            }

            try {
                $model->save();
                $this->messageManager->addSuccess(__('You saved the page.'));
                $this->dataPersistor->clear('cms_page');
                if ($this->getRequest()->getParam('back')) {
                    return $resultRedirect->setPath('*/*/edit', ['page_id' => $model->getId(), '_current' => true]);
                }
                return $resultRedirect->setPath('*/*/');
            } catch (LocalizedException $e) {
                $this->messageManager->addError($e->getMessage());
            } catch (\Exception $e) {
                $this->messageManager->addException($e, __('Something went wrong while saving the page.'));
            }

            $this->dataPersistor->set('cms_page', $data);
            return $resultRedirect->setPath('*/*/edit', ['page_id' => $this->getRequest()->getParam('page_id')]);
        }
        return $resultRedirect->setPath('*/*/');
    }
}
?>

Step 6. Create DataProvider.php

Create DataProvider.php under [Vendor]\Module\Model\Cms\Page. Your File location will be [Vendor]\Module\Model\Cms\Page\DataProvider.php

<?php
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace [Vendor]\[Module]\Model\Cms\Page;

use Magento\Cms\Model\ResourceModel\Page\CollectionFactory;
use Magento\Framework\App\Request\DataPersistorInterface;

/**
 * Class DataProvider
 */
class DataProvider extends \Magento\Cms\Model\Page\DataProvider
{

    /**
     * Get data
     *
     * @return array
     */
    public function getData()
    {
        if (isset($this->loadedData)) {
            return $this->loadedData;
        }
        $items = $this->collection->getItems();
        /** @var $page \Magento\Cms\Model\Page */
        foreach ($items as $page) {
            $this->loadedData[$page->getId()] = $page->getData();
        }

        $data = $this->dataPersistor->get('cms_page');


        if (!empty($data)) {
            $page = $this->collection->getNewEmptyItem();

            $page->setData($data);
            $this->loadedData[$page->getId()] = $page->getData();
            $this->dataPersistor->clear('cms_page');
        }
        /* For Modify  You custom image field data */
        if(!empty($this->loadedData[$page->getId()]['your_image_field_name'])){
            $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
            $storeManager = $objectManager->get('Magento\Store\Model\StoreManagerInterface');
            $currentStore = $storeManager->getStore();
            $media_url=$currentStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);

            $image_name=$this->loadedData[$page->getId()]['your_image_field_name'];
            unset($this->loadedData[$page->getId()]['your_image_field_name']);
            $this->loadedData[$page->getId()]['your_image_field_name'][0]['name']=$image_name;
            $this->loadedData[$page->getId()]['your_image_field_name'][0]['url']=$media_url."cms/hero/tmp/".$image_name;
        }
        return $this->loadedData;
    }
}

Note. Please Replace "your_image_field_name" with your field name.

enter image description here

1

I would add to etc/adminhtml/di.xml

<virtualType name="Magento\Catalog\CategoryImageUpload" type="Magento\Catalog\Model\ImageUploader">
    <arguments>
        <argument name="baseTmpPath" xsi:type="string">your path here</argument>
        <argument name="basePath" xsi:type="string">your path here</argument>
        <argument name="allowedExtensions" xsi:type="array">
            <item name="jpg" xsi:type="string">jpg</item>
            <item name="jpeg" xsi:type="string">jpeg</item>
            <item name="gif" xsi:type="string">gif</item>
            <item name="png" xsi:type="string">png</item>
        </argument>
    </arguments>
</virtualType>
<type name="[Vendor]\[Module]\Controller\Adminhtml\Cms\Heroimage\Upload">
    <arguments>
        <argument name="imageUploader" xsi:type="object">Magento\Catalog\CategoryImageUpload</argument>
    </arguments>
</type>

and

replace in DataProvider.php

 if(!empty($this->loadedData[$page->getId()]['your_image_field_name']))
to
 if (!empty($this->loadedData))

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.