Hello there! Here is our first blog post about Magento 2. Better late than never.
We assumed that it would be nice to have similar functionality for Magento 2. It means you don’t need to search for the product on frontend while you’re editing it in the admin to be able to check how your changes look like. You can just click the button and voilà! So this article describes how to do it.
First of all you need to create a folder app/code/HexBrain/ProductView
where HexBrain
is the vendor name and ProductView
is the extension name. You can call it differently but in this case you should modify all the following code examples. The second step is creating composer.json
file. Starting from Magento 2.2 it is a requirement, you can correct me if I’m wrong. The following code is content of the file from our extension. It should be exactly inside the folder mentioned before.
{
"name": "hexbrain/productview",
"description": "N/A",
"require": {
"php": "~7.0.0|~7.1.0"
},
"type": "magento2-module",
"version": "1.0.0",
"license": [
"GNU-3.0"
],
"authors": [
{
"name": "Nick Kravchuk",
"email": "nick@hexbrain.com",
"homepage": "http://www.hexbrain.com/",
}
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"HexBrain\\ProductView\\": ""
}
}
}
After this you need to let Magento know that your extension exists. So you need to create registration.php
:
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'HexBrain_ProductView',
__DIR__
);
The very next step is creating subfolder etc
with config.xml
file inside:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="HexBrain_ProductView" setup_version="1.0.0"></module>
</config>
There is nothing special, only extension version info.
It was the easiest part of the extension. So what’s next? We need to add the button to product edit page in admin. The solution is to create a layout file, but how to register a layout file? The answer is you don’t need to, unlike in Magento 1. You just need to create a layout file catalog_product_edit.xml
in subfolder view/adminhtml/layout/
. Why it should have such a name? I think it’s a theme for another article :)
The layout file contains instruction which lets Magento know that it needs to put a block with the button into the toolbar block on the product edit page
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="page.actions.toolbar">
<block class="HexBrain\ProductView\Block\Adminhtml\ViewProductButton" as="view_product_button"/>
</referenceBlock>
</body>
</page>
The next step will be creating a block file ViewProductButton.php
in the directory Block/Adminhtml/
. Here is the content of this file:
<?php
namespace HexBrain\ProductView\Block\Adminhtml;
class ViewProductButton extends \Magento\Backend\Block\Widget\Container
{
/**
* @var \Magento\Catalog\Model\Product
*/
protected $_product;
/**
* Core registry
*
* @var \Magento\Framework\Registry
*/
protected $_coreRegistry = null;
/**
* App Emulator
*
* @var \Magento\Store\Model\App\Emulation
*/
protected $_emulation;
/**
* @param \Magento\Backend\Block\Widget\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Catalog\Model\Product $product
* @param \Magento\Store\Model\App\Emulation $emulation
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Widget\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Catalog\Model\Product $product,
\Magento\Store\Model\App\Emulation $emulation,
array $data = []
)
{
$this->_coreRegistry = $registry;
$this->_product = $product;
$this->_request = $context->getRequest();
$this->_emulation = $emulation;
parent::__construct($context, $data);
}
/**
* Block constructor adds buttons
*
*/
protected function _construct()
{
$this->addButton(
'preview_product',
$this->getButtonData()
);
parent::_construct();
}
/**
* Return button attributes array
*/
public function getButtonData()
{
return [
'label' => __('View'),
'on_click' => sprintf("window.open('%s')", $this->_getProductUrl()),
'class' => 'view disable',
'sort_order' => 20
];
}
/**
* Return product frontend url depends on active store
*
* @return mixed
*/
protected function _getProductUrl()
{
$store = $this->_request->getParam('store');
if (!$store) {
$this->_emulation->startEnvironmentEmulation(null, \Magento\Framework\App\Area::AREA_FRONTEND, true);
$productUrl = $this->_product->loadByAttribute('entity_id', $this->_coreRegistry->registry('product')->getId())->getProductUrl();
$this->_emulation->stopEnvironmentEmulation();
return $productUrl;
} else {
return $this->_product
->loadByAttribute('entity_id', $this->_coreRegistry->registry('product')->getId()
)->setStoreId($store)->getUrlInStore();
}
}
}
We inject the product model here to be able to manage products, we use \Magento\Framework\Registry
it allows to get current product. Also we use \Magento\Store\Model\App\Emulation
it allows to emulate frontend, otherwise the function getProductUrl
returns the admin url.
That’s all. But actually it’s not. Where are the tests? You can find everything here including the ready extension Product View Button. Keep calm and create the pull requests.