2

I need to edit the existing product detail page by adding more images and description under them. But I need to automate this function from the backend also. Something like adding 1st image and the relevant detail for the image. Then again 2nd image and the relevant detail for the 2nd image. I need to add about 5 figures but product to product it can be varied. These details should be added from the admin panel. As the figure below.

enter image description here

How should I do this? Adding a module will solve this? But I need to edit the existing product detail page.

3

Yes creating a module will solve this.

Tested on magento 2.2.3

The following two files will register your new module with the Magento 2 system.

app/code/Vendor/Package/registration.php

<?php
 \Magento\Framework\Component\ComponentRegistrar::register(
     \Magento\Framework\Component\ComponentRegistrar::MODULE,
     'Vendor_Package',
      __DIR__
 );

app/code/Vendor/Package/etc/module.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_Package" setup_version="1.0.0" />
</config>

app/code/Vendor/Package/Setup/InstallData.php

Setup new attributes

<?php
namespace Vendor\Package\Setup;

use Magento\Catalog\Model\Product;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class InstallData implements InstallDataInterface
{


private $eavSetupFactory;

public function __construct(
    EavSetupFactory $eavSetupFactory
)
{
    $this->eavSetupFactory = $eavSetupFactory;
}

public function install(
     ModuleDataSetupInterface $setup, 
     ModuleContextInterface $context
)
{
    $setup->startSetup();

    /** @var \Magento\Eav\Setup\EavSetup $eavSetup */
    $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

    $eavSetup->addAttribute(
        Product::ENTITY,
        'extra_product_image_1',
        [
        'type'                    => 'varchar',
        'label'                   => 'Extra Product Image 1',
        'input'                   => 'media_image',
        'frontend'                => 'Magento\Catalog\Model\Product\Attribute\Frontend\Image',
        'required'                => false,
        'global'                  => ScopedAttributeInterface::SCOPE_STORE,
        'used_in_product_listing' => true,
    ]);

    $eavSetup->addAttribute(
        Product::ENTITY,
        'extra_product_image_2',
        [
        'type'                    => 'varchar',
        'label'                   => 'Extra Product Image 2',
        'input'                   => 'media_image',
        'frontend'                => 'Magento\Catalog\Model\Product\Attribute\Frontend\Image',
        'required'                => false,
        'global'                  => ScopedAttributeInterface::SCOPE_STORE,
        'used_in_product_listing' => true,
    ]);

    $eavSetup->addAttribute(
        \Magento\Catalog\Model\Product::ENTITY,
        'image_description_1',
        [
            'type' => 'text',
            'backend' => '',
            'frontend' => '',
            'label' => 'Image Description 1',
            'input' => 'text',
            'class' => '',
            'source' => '',
            'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
            'visible' => true,
            'required' => true,
            'user_defined' => false,
            'default' => '',
            'searchable' => false,
            'filterable' => false,
            'comparable' => false,
            'visible_on_front' => false,
            'used_in_product_listing' => true,
            'unique' => false,
            'apply_to' => ''
        ]
    );

    $eavSetup->addAttribute(
        \Magento\Catalog\Model\Product::ENTITY,
        'image_description_2',
        [
            'type' => 'text',
            'backend' => '',
            'frontend' => '',
            'label' => 'Image Description 2',
            'input' => 'text',
            'class' => '',
            'source' => '',
            'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
            'visible' => true,
            'required' => true,
            'user_defined' => false,
            'default' => '',
            'searchable' => false,
            'filterable' => false,
            'comparable' => false,
            'visible_on_front' => false,
            'used_in_product_listing' => true,
            'unique' => false,
            'apply_to' => ''
        ]
    );
  $setup->endSetup();
}
}

At this point you have created a new module that installs your attributes for all products. You'll be able to see the input fields on the product edit page and when you upload an Image you'll see a new image role to assign -- this is important; generally in this use case you'll want to hide this image as well (an option when assigning image roles). new input attributes new image roles

Now you'll want to create a Block Class.

app/code/Vendor/Package/Block/ProductImage.php

<?php

 namespace Vendor\Package\Block;

 use Magento\Catalog\Api\CategoryRepositoryInterface;
 use Magento\Framework\App\Filesystem\DirectoryList;

 class ProductImage extends \Magento\Catalog\Block\Product\ListProduct implements \Magento\Framework\DataObject\IdentityInterface
 {
 /**
 * @var \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory
 */
protected $_collectionFactory;

/**
 * @var \Magento\Catalog\Helper\ImageFactory
 */
protected $_imageFactory;

/**
 * @var \Magento\Framework\Registry
 */
protected $_registry;

/**
 * @var \Magento\Framework\App\Filesystem\DirectoryList
 */
protected $_filesystem;

/**
 * @var \Magento\Catalog\Helper\Image
 */
protected $_productImageHelper;

/**
 * @var \Magento\Store\Model\StoreManagerInterface
 */
protected $_storeManager;

/**
 * ListProduct constructor.
 * @param \Magento\Catalog\Block\Product\Context $context
 * @param \Magento\Framework\Data\Helper\PostHelper $postDataHelper
 * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver
 * @param CategoryRepositoryInterface $categoryRepository
 * @param \Magento\Framework\Url\Helper\Data $urlHelper
 * @param \FishPig\WordPress\Model\ResourceModel\Post\Collection $wpPost
 * @param \Magento\Catalog\Helper\ImageFactory $imageFactory
 * @param \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $collectionFactory
 * @param array $data
 */
public function __construct(
    \Magento\Catalog\Block\Product\Context $context,
    \Magento\Framework\Data\Helper\PostHelper $postDataHelper,
    \Magento\Catalog\Model\Layer\Resolver $layerResolver,
    CategoryRepositoryInterface $categoryRepository,
    \Magento\Framework\Url\Helper\Data $urlHelper,
    \Magento\Catalog\Helper\Image $imageFactory,
    \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $collectionFactory,
    \Magento\Framework\Registry $registry,
    \Magento\Framework\Filesystem $filesystem,
    \Magento\Catalog\Helper\Image $productImageHelper,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    array $data = []
) {
    $this->_collectionFactory = $collectionFactory;
    $this->_imageFactory = $imageFactory;
    $this->_registry = $registry;
    $this->_filesystem = $filesystem;
    $this->_storeManager = $storeManager;
    $this->_productImageHelper = $productImageHelper;
    parent::__construct(
        $context,
        $postDataHelper,
        $layerResolver,
        $categoryRepository,
        $urlHelper,
        $data
    );
}

 public function getCurrentProduct()
 {
    return $this->_registry->registry('current_product');
 }

 public function getMediaDir() {
    return rtrim($this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA), '/');
 }
}

app/code/Vendor/Package/view/frontend/layout/catalog_product_view.xml

Now lets link up your block class to your template file!

   <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content.aside">
            <container name="extra.product.image.container" htmlTag="div" htmlClass="extra-product-image__outer" before="-">
                <block name="extra.product.overview" class="Vendor\Package\Block\ProductImage" template="Vendor_Package::extra-product-image.phtml" />
            </container>
        </referenceContainer>
    </body>
</page>

Vendor/Package/view/frontend/templates/extra-product-image.phtml

Your template file.

<?php

$currentProduct = $block->getCurrentProduct();
$mediaDirectory = $block->getMediaDir();
$image1 = $mediaDirectory . "/catalog/product" . $currentProduct->getExtraProductImage1();
$image2 = $mediaDirectory . "/catalog/product" . $currentProduct->getExtraProductImage2();
$description1 = $currentProduct->getImageDescription1() ?? '';
$description2 = $currentProduct->getImageDescription2() ?? '';
?>

<div>
    <img src="<?=$image1;?>" >
    <p><?=$description1?></p>
    <img src="<?=$image2;?>" >
    <p><?=$description2;?></p>
</div>

Using the Magento 2 cli run the following.

magento module:enable Vendor_Package; magento setup:upgrade; magento setup:di:compile; magento setup:static-content:deploy -f; 

Now for each product you'll have the ability to control the new data.

2

There are few steps mentioned in this manual. I will go through the main ones.

In this section of the guide, you’ll learn how to create and manage content pages and blocks, and use variables and widgets to add dynamic content... https://docs.magento.com/m2/ce/user_guide/cms/content-elements.html

From Admin:

1- Create a Static CMS Block from Content -> under Elements -> Blocks Adding CMS Blocks

2- Create a Widget to use the CMS Static Block we just created. Go to: Content -> under Elements -> Widgets Adding a Widgets


Here's a walkthrough with images:

  1. First thing, open Blocks page from Admin.

Step 1

enter image description here

  1. Start a new Block. Fill in information, add your content in WYSIWYG and in HTML. You may use classes for your HTML and then assign styles to these classes from your template LESS.

Step 2

  1. Start a new Widget and fill in the required info.

Step 3 A

For your case, Type is the CMS Static Block. Try to explore other variations.

STep 3 a

  1. Select which page to show that widget on and where.

Step 4

  1. Select the static block you already created in Step 1

Step 5

Here you see the result. The CMS Static Block will show on all of my Simple Product because I selected so from the widget.

Step 6 Final

The same thing can be achieved from references in xml files and phtml. I have no experience with these two. The manual will definitely provide more information.

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.