Let me discuss one interesting problem which I faced with Magento 2.
In Magento 2 Store, I’ve faced an issue with the product URL to access the product page. I need to remove the category path from the Product URL when I access any product page.
I found one admin configuration in Magento Admin at the below path to remove the category path from the product URL.
Path: Admin > STORES > Settings > Configuration > CATALOG > Catalog > Search Engine Optimization
- Set “Use Categories Path for Product URLs” option to No.
- After update this configuration, please clean config and full_page cache types and check the product URL.
Now, You can see the category path is removed when you access the product page from the product listing page.
But still, I can access the product page using the product URL with the category path.
For example,
Let’s take an example of the Magento Sample Data’s product name with “Olivia 1/4 Zip Light Jacket”
You can access the product detail page with below URLs by directly entering in the Address Bar of the browser:
- http://magento2.demo.ubertheme.com/women/tops-women/jackets-women/olivia-1-4-zip-light-jacket.html
- It includes the category path in product URL
- http://magento2.demo.ubertheme.com/olivia-1-4-zip-light-jacket.html
Here, I need to prevent the product page access when the URL includes the category path.
So As a solution, I decided If I got the category path in product URL I’ll redirect it to the product URL without category path.
I’ve achieved this solution by creating an after Plugin on findOneByData() function of the Magento\UrlRewrite\Model\Storage\AbstractStorage model class.
Please follow the below steps to implement this solution to omit the category path from the product URL to access the product page.
Step 1: Create a custom module under app/code
directory with two require file registration.php
and etc/module.xml
.
File Path: /app/code/Aureatelabs/DemoModule/registration.php
- Where Aureatelabs is a vendor name and DemoModule is a module name.
<?php
/**
* DemoModule
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
*
* @category DemoModule
* @package Aureatelabs_DemoModule
* @license http://www.gnu.org/licenses/gpl-3.0.html
*/
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Aureatelabs_DemoModule',
__DIR__
);
File Path: /app/code/Aureatelabs/DemoModule/etc/module.xml
<?xml version="1.0" ?>
<!--
/**
* DemoModule
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
*
* @category DemoModule
* @package Aureatelabs_DemoModule
* @license http://www.gnu.org/licenses/gpl-3.0.html
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Aureatelabs_DemoModule" setup_version="1.0.0">
<sequence>
<module name="Magento_Catalog"/>
<module name="Magento_UrlRewrite"/>
</sequence>
</module>
</config>
Step 2: Create a di.xml
file under etc directory to define a plugin.
File Path: /app/code/Aureatelabs/DemoModule/etc/di.xml
<?xml version="1.0" ?>
<!--
/**
* DemoModule
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
*
* @category DemoModule
* @package Aureatelabs_DemoModule
* @license http://www.gnu.org/licenses/gpl-3.0.html
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\UrlRewrite\Model\Storage\AbstractStorage">
<plugin disabled="false" name="Plugin_Magento_Checkout_Block_Onepage" sortOrder="10" type="Aureatelabs\DemoModule\Plugin\FindOneByData"/>
</type>
</config>
Step 3: Create a plugin class under Plugin directory.
File Path: /app/code/Aureatelabs/DemoModule/Plugin/FindOneByData.php
<?php
namespace Aureatelabs\DemoModule\Plugin;
use Magento\Framework\App\Config\ScopeConfigInterface;
/**
* Class FindOneByData
* @package Aureatelabs\DemoModule\Plugin
*/
class FindOneByData
{
/**
* @var ScopeConfigInterface
*/
protected $scopeConfig;
/**
* FindOneByData constructor.
* @param ScopeConfigInterface $scopeConfig
*/
public function __construct(
ScopeConfigInterface $scopeConfig
) {
$this->scopeConfig = $scopeConfig;
}
/**
* @param \Magento\UrlRewrite\Model\Storage\AbstractStorage $subject
* @param $result
* @param array $data
* @return mixed
*/
public function afterFindOneByData(
\Magento\UrlRewrite\Model\Storage\AbstractStorage $subject,
$result,
array $data
) {
if(!empty($result) && !(bool)$this->scopeConfig->getValue('catalog/seo/product_use_categories')
&& $result->getEntityType() == 'product'
&& (strpos(trim($result->getRequestPath(), '/'), '/') !== false)
) {
$requestPathArr = explode('/', $result->getRequestPath());
if (count($requestPathArr) > 1) {
$newRequestPath = end($requestPathArr);
$result->setTargetPath($newRequestPath);
$result->setRedirectType(301);
}
}
return $result;
}
}
This solution will work if the “Use Categories Path for Product URLs” option is set to No from the Magento backend. The Magento configuration path for this option is mentioned above.
Step 4: Please enabled and install the module using the below commands.
php bin/magento module:enable Aureatelabs_DemoModule
php bin/magento setup:upgrade
php bin/magento setup:di:compile
Please verify module functionality by entering product URL with category path directly in the address bar of the browser, it will redirect to the product URL without category path.
Enjoy Coding.
Thank you.
Thank you so much, works perfect!