Add a static URL prefix for product and category Magento 2
-
15-04-2021 - |
题
I need to specify a prefix static string for all URLs of my Products and Categories. Just like Wordpress Woocommerce permalinks.
For example all of Categories should have product-category
prefix in their URL:
- Cat One:
domain.com/product-category/cat-one
- Cat Two (child of 'Cat One'):
domain.com/product-category/cat-one/cat-two
and all of Products should have product
URL prefix, no matter what their Category is:
- Product One:
domain.com/product/product-one
- Product Two:
domain.com/product/product-two
I tried to do this solution, but It's for 3 years ago and not working in Magento 2.
Also this extension is for Magento 1.x as you see.
By the way, I'm using Magento 2.1.9 with PHP 7.0.22 and XAMPP 3.2.2.
Thanks.
解决方案
I found a good solution for this situation!
We need to make our custom module for extending Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator
class with plugin methods and Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator
class with preference class (because we need to change inside of its methods, not change after or before them).
Assume that our custom module created by this documentation, has <Vendor>
and <Module>
names.
1) So, at first we need to define our plugin and preference class in our
etc/di.xml
file:
<?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\CatalogUrlRewrite\Model\ProductUrlPathGenerator" type="<Vendor>\<Module>\Model\CatalogUrlRewrite\ProductUrlPathGenerator"/>
<type name="Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator">
<plugin name="my_category_url_path_generator" type="<Vendor>\<Module>\Plugin\Model\CategoryUrlPathGenerator" sortOrder="15"/>
</type>
</config>
2) Add these classes in proper addresses:
a) Our preference class in
<Vendor>\<Module>\Model\CatalogUrlRewrite\ProductUrlPathGenerator.php
:--> Change this two constant in this class for your own custom static route: <--
<?php
namespace <Vendor>\<Module>\Model\CatalogUrlRewrite;
class ProductUrlPathGenerator extends \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator
{
// CHANGE THESE FOR CUSTOM STATIC PREFIX ROUTE of PRODUCT and PRODUCT CATEGORY
const PRODUCT_PREFIX_ROUTE = 'product';
const CATEGORY_PREFIX_ROUTE = 'product-category';
/**
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
* @param \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
*/
public function __construct(
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator,
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository
) {
parent::__construct($storeManager, $scopeConfig, $categoryUrlPathGenerator, $productRepository);
}
/**
* Retrieve Product Url path (with category if exists)
*
* @param \Magento\Catalog\Model\Product $product
* @param \Magento\Catalog\Model\Category $category
*
* @return string
*/
public function getUrlPath($product, $category = null)
{
$path = $product->getData('url_path');
if ($path === null) {
$path = $product->getUrlKey()
? $this->prepareProductUrlKey($product)
: $this->prepareProductDefaultUrlKey($product);
}
if ($category !== null) {
$categoryUrl = str_replace(self::CATEGORY_PREFIX_ROUTE .'/','',$this->categoryUrlPathGenerator->getUrlPath($category));
$path = $categoryUrl . '/' . $path;
}
return self::PRODUCT_PREFIX_ROUTE . '/' . $path;
}
}
b ) Our plugin class in
<Vendor>\<Module>\Plugin\Model\CategoryUrlPathGenerator.php
:
<?php
namespace <Vendor>\<Module>\Plugin\Model;
class CategoryUrlPathGenerator
{
/**
* Add a static prefix to category URL path
*
* @param \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $subject
* @param $path
* @return string
*/
public function afterGetUrlPath(\Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $subject, $path)
{
if (strpos($path, \<Vendor>\<Module>\Model\CatalogUrlRewrite\ProductUrlPathGenerator::CATEGORY_PREFIX_ROUTE) === false)
$path = \<Vendor>\<Module>\Model\CatalogUrlRewrite\ProductUrlPathGenerator::CATEGORY_PREFIX_ROUTE . $path;
return $path;
}
}
3) Run this command:
php bin/magento setup:upgrade
And its DONE!, now you can create products and their categories and you'll see the url rewrites that created with these static url prefixes.
DO NOT forget to change
<Vendor>
,<Module>
with your own custom module names and change the constants ofProductUrlPathGenerator
class for change to your custom static prefixes.
Good luck.