3

I want to remove the parent category from the subcategory URL.

For example, I would like to change:

www.magento2.com/Category1/Category2/gear/bags.html      

to

www.magento2.com/bags.html       

Is there any way to programmatically remove parent category from subcategory URL?

  • So, what happens if www.magento2.com/bag1/bag2/bag3.html? – Khoa TruongDinh Sep 6 '16 at 13:58
  • 1
    www.magento2.com/bag3.html – Pavil Sep 6 '16 at 13:59
4

If you look at the class Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator which is responsible for the category URL rewrite generation, you will see that it uses a constant value to determine if the parent path should be added:

protected function isNeedToGenerateUrlPathForParent($category)
{
    return $category->isObjectNew() || $category->getLevel() >= self::MINIMAL_CATEGORY_LEVEL_FOR_PROCESSING;
}

The value is

const MINIMAL_CATEGORY_LEVEL_FOR_PROCESSING = 3;

which means the path is generated for every category that is not a top category (level 1 is the root category) and you cannot configure this value or turn off parent path generation.

And since it is a protected method we cannot modify the return value with a plugin. Instead you will have to write a plugin for the public method getUrlPath() that uses isNeedToGenerateUrlPathForParent().

I would use an around plugin which does not call the original method, essentially replacing the method:

class RemoveParentCategoryPathPlugin
{
    public function aroundGetUrlPath($subject, $proceed, $category)
    {
        if (in_array($category->getParentId(), [Category::ROOT_CATEGORY_ID, Category::TREE_ROOT_ID])) {
            return '';
        }
        $path = $category->getUrlPath();
        if ($path !== null && !$category->dataHasChangedFor('url_key') && !$category->dataHasChangedFor('parent_id')) {
            return $path;
        }
        $path = $category->getUrlKey();
        if ($path === false) {
            return $category->getUrlPath();
        }
        return $path;
    }
}

(this is the original method, but without the parent path generation)

Plugin documentation: http://devdocs.magento.com/guides/v2.1/extension-dev-guide/plugins.html

Update existing categories

This will apply for new categories. Unfortunately the category URLs are not generated by an indexer anymore, so reindexing does not change them and the only way to regenerate them is to save each category. It could be done with a one-off script that loads a collection of all categories and calls save() on it:

$allCategories = $categoryCollectionFactory->create()->load();
foreach ($allCategories as $category) {
    $category->setDataChanges(true);
    $category->save();
}

Note that this is not optimized for performance at all and will load all categories at once. So if you have thousands of categories you might want to process them in batches.

  • I tried to create the plugin, but doesn't seems to have any effect. for example - I have created a file RemoveParentCategoryPathPlugin.php in Myweb/RemoveParentCategoryPathPlugin/plugin/ and created di.xml in etc folder with contents like ` <type name="Magento\CatalogUrlRewrite\Model"> <plugin name="Myweb_RemoveParentCategoryPathPlugin" type="Myweb\RemoveParentCategoryPathPlugin\Plugin\RemoveParentCategoryPathPlugin" /> </type> – Joshi Jul 7 '18 at 15:27
  • in addition to above I have created the registration.php and module.xml. Also created some new child categories, but still parent categories show up. – Joshi Jul 7 '18 at 15:27
  • Hi Fabian - can you take a look at - magento.stackexchange.com/questions/232750/… - what I am missing. – Joshi Jul 7 '18 at 21:50
0
vendor/magento/module-catalog-url-rewrite/Model/CategoryUrlPathGenerator.php around line 75

comment out these lines under the function getUrlPath($category) i.e.

/* if ($this->isNeedToGenerateUrlPathForParent($category)) {
            $parentPath = $this->getUrlPath(
                $this->categoryRepository->get($category->getParentId(), $category->getStoreId())
            );
            $path = $parentPath === '' ? $path : $parentPath . '/' . $path;
            $path = '';

        } */

And then reindex and clean up the cache. Also, Don't forget to re-save the categories (that were created prior to making the above mentioned edits).

Is code concept is not correct because after importing removing parent category it is not possible and Overriding CategoryUrlPathGenerator.php makes error in product importing.

This is not advisable

-1

for getting rid of category name from subcategory URL you need to edit the ---

vendor/magento/module-catalog-url-rewrite/Model/CategoryUrlPathGenerator.php around line 75

comment out these lines under the function getUrlPath($category) i.e.

/* if ($this->isNeedToGenerateUrlPathForParent($category)) {
            $parentPath = $this->getUrlPath(
                $this->categoryRepository->get($category->getParentId(), $category->getStoreId())
            );
            $path = $parentPath === '' ? $path : $parentPath . '/' . $path;
            $path = '';

        } */

And then reindex and clean up the cache. Also Don't forget to re-save the categories (that were created prior to making the above mentioned edits).

  • so the solution works maybe you could have mentioned it's -1ed for reformatting the text. – mint high Oct 12 '16 at 9:03

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.