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