0

The site I am migrating over to Magento from Virtuemart used only the top level parent category in the product url path. The client insists on not having to redirect a bunch of traffic once we launch. So I am looking for a way to display only the top level parent in the product url.

If I have a product located in Hand Tools, like so: Root Category > Tools > Hand Tools > Product

Currently Magento creates product url as: http://anystore.com/tools/hand-tools/product

I would like Magento to create the product url as: http://anystore.com/tools/product

Is this possible without the use of a whole lot of url rewrites.

1

Make sure "Create permanent redirect" is off in the SEO settings under System > Configuration > Catalog, otherwise you may end up with a ton of redirects after this change.

The catalog URL is prepended in Mage_Catalog_Model_Url::getProductRequestPath(). This method is far too big and delegates to general purpose methods, so unfortunately, if you rewrite it, you will need to copy the entire function and add two lines.

Here's the module as a patch:

diff --git a/app/code/community/MageStack/ShorterUrl/Model/Url.php b/app/code/community/MageStack/ShorterUrl/Model/Url.php
new file mode 100644
index 0000000..336d1d7
--- /dev/null
+++ b/app/code/community/MageStack/ShorterUrl/Model/Url.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Creates shorter URLs for products by only adding the top-level category.
+ */
+class MageStack_ShorterUrl_Model_Url extends Mage_Catalog_Model_Url
+{
+    /**
+     * Get unique product request path
+     *
+     * @param   Varien_Object $product
+     * @param   Varien_Object $category
+     * @return  string
+     */
+    public function getProductRequestPath($product, $category)
+    {
+        if ($product->getUrlKey() == '') {
+            $urlKey = $this->getProductModel()->formatUrlKey($product->getName());
+        } else {
+            $urlKey = $this->getProductModel()->formatUrlKey($product->getUrlKey());
+        }
+        $storeId = $category->getStoreId();
+        $suffix  = $this->getProductUrlSuffix($storeId);
+        $idPath  = $this->generatePath('id', $product, $category);
+        /**
+         * Prepare product base request path
+         */
+        if ($category->getLevel() > 1) {
+            // To ensure, that category has path either from attribute or generated now
+            $this->_addCategoryUrlPath($category);
+            $categoryUrl = Mage::helper('catalog/category')->getCategoryUrlPath($category->getUrlPath(),
+                false, $storeId);
+            if( strpos($categoryUrl, '/') )
+                $categoryUrl = substr($categoryUrl, 0, strpos($categoryUrl, '/'));
+            $requestPath = $categoryUrl . '/' . $urlKey;
+        } else {
+            $requestPath = $urlKey;
+        }
+
+        if (strlen($requestPath) > self::MAX_REQUEST_PATH_LENGTH + self::ALLOWED_REQUEST_PATH_OVERFLOW) {
+            $requestPath = substr($requestPath, 0, self::MAX_REQUEST_PATH_LENGTH);
+        }
+
+        $this->_rewrite = null;
+        /**
+         * Check $requestPath should be unique
+         */
+        if (isset($this->_rewrites[$idPath])) {
+            $this->_rewrite = $this->_rewrites[$idPath];
+            $existingRequestPath = $this->_rewrites[$idPath]->getRequestPath();
+
+            if ($existingRequestPath == $requestPath . $suffix) {
+                return $existingRequestPath;
+            }
+
+            $existingRequestPath = preg_replace('/' . preg_quote($suffix, '/') . '$/', '', $existingRequestPath);
+            /**
+             * Check if existing request past can be used
+             */
+            if ($product->getUrlKey() == '' && !empty($requestPath)
+                && strpos($existingRequestPath, $requestPath) === 0
+            ) {
+                $existingRequestPath = preg_replace(
+                    '/^' . preg_quote($requestPath, '/') . '/', '', $existingRequestPath
+                );
+                if (preg_match('#^-([0-9]+)$#i', $existingRequestPath)) {
+                    return $this->_rewrites[$idPath]->getRequestPath();
+                }
+            }
+
+            $fullPath = $requestPath.$suffix;
+            if ($this->_deleteOldTargetPath($fullPath, $idPath, $storeId)) {
+                return $fullPath;
+            }
+        }
+        /**
+         * Check 2 variants: $requestPath and $requestPath . '-' . $productId
+         */
+        $validatedPath = $this->getResource()->checkRequestPaths(
+            array($requestPath.$suffix, $requestPath.'-'.$product->getId().$suffix),
+            $storeId
+        );
+
+        if ($validatedPath) {
+            return $validatedPath;
+        }
+        /**
+         * Use unique path generator
+         */
+        return $this->getUnusedPath($storeId, $requestPath.$suffix, $idPath);
+   }
+}
\ No newline at end of file
diff --git a/app/code/community/MageStack/ShorterUrl/etc/config.xml b/app/code/community/MageStack/ShorterUrl/etc/config.xml
new file mode 100644
index 0000000..8490fe1
--- /dev/null
+++ b/app/code/community/MageStack/ShorterUrl/etc/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<config>
+    <modules>
+        <MageStack_ShorterUrl>
+            <version>1.0.0</version>
+        </MageStack_ShorterUrl>
+    </modules>
+    <global>
+        <models>
+            <magestack_shorterurl>
+                <class>MageStack_ShorterUrl_Model</class>
+            </magestack_shorterurl>
+            <catalog>
+                <rewrite>
+                    <url>MageStack_ShorterUrl_Model_Url</url>
+                </rewrite>
+            </catalog>
+        </models>
+    </global>
+</config>
\ No newline at end of file
diff --git a/app/etc/modules/MageStack_ShorterUrl.xml b/app/etc/modules/MageStack_ShorterUrl.xml
new file mode 100644
index 0000000..f1101eb
--- /dev/null
+++ b/app/etc/modules/MageStack_ShorterUrl.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<config>
+    <modules>
+        <MageStack_ShorterUrl>
+            <active>true</active>
+            <codePool>community</codePool>
+            <depends><Mage_Catalog/></depends>
+        </MageStack_ShorterUrl>
+    </modules>
+</config>
\ No newline at end of file
-- 
1.9.1
0

app/code/core/Mage/Catalog/Model/Url.php

public function getProductRequestPath($product, $category) { if ($category->getLevel() > 1) { ... $categoryUrl = Mage::helper('catalog/category')->getCategoryUrlPath($category->getUrlPath(), false, $storeId);

    /*add*/
    if(strpos($categoryUrl, '/')){
        $categoryUrl = substr($categoryUrl, 0, strpos($categoryUrl, '/'));
    }
    /*add*/

    $requestPath = $categoryUrl . '/' . $urlKey;
    }

}

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.