防止创建的在产品 URL 中包含类别 URL 键的自动 URL 重写

Posted

技术标签:

【中文标题】防止创建的在产品 URL 中包含类别 URL 键的自动 URL 重写【英文标题】:Prevent automatic URL rewrites created that include category URL key in product URL 【发布时间】:2015-06-12 16:13:38 【问题描述】:

每当我创建新产品时,Magento 会自动创建不必要的 URL 重写,包括每个类别和子类别组合,在产品路径中使用类别的 URL 键。例如,对于具有以下类别的产品 product-name

category category > subcategory category > subcategory > third

...Magento 将使用以下请求路径自动创建 URL 重写:

/category/product-name /category/subcategory/product-name /category/subcategory/third/product-name

...以及使用请求路径创建正在使用的 URL 重写:

/product-name

我的问题是,即使我将设置 Use Categories Path for Product URLs 设置为 No 在:

System > Configuration > Catalog > Search Engine Optimizations

...如何阻止这些额外的 URL 重写被自动创建?

现在,我再次意识到该网站并未链接到网站上任何地方的这些额外路径,但如果出于某种原因搜索引擎选择了:

http://example.com/category/subcategory/third/product-name

...这将加载!我很紧张这会导致搜索引擎索引重复的内容。由于Use Categories Path for Product URLs 设置设置为No,并且网站上所有指向该产品的链接都指向:

http://example.com/product-name

...我想阻止 Magento 自动创建这些不必要的 URL 重写。

作为参考,我尝试将core_url_rewrite 表截断为零(基本上将其清空)并​​重新索引System > Index Management 中的目录 URL 重写。这仍然会导致 Magento 自动创建这些不必要的 URL 重写。

另外,作为参考,我使用的是 Magento Community 1.9.1。

请指教!非常感谢您的帮助。

【问题讨论】:

【参考方案1】:

问题不仅与规范链接有关,还主要是另一个问题:抓取预算。你不想浪费你的抓取预算,所以不必要的网址需要去。

您应该通过 shell 脚本修改 core_url_rewrite 中的每个条目:

is_system = 1 product_id 不为空 category_id 不为空

你设置好了:

target_path = 直接产品网址 选项 = RP

现在您创建了 301 重定向到真实页面,只剩下一个问题:

如果一个产品没有 category-product-urls,如果通过后端配置设置关闭该功能,则不会创建其他 url,这就是我们想要的。 但是,如果一个产品还有 category-product-urls 并且您将此产品添加到一个类别中,仍然会创建一个新的 category-product-url。所以你需要通过重写/扩展 Mage_Catalog_Model_Url 来改变一种方法:

 /**
     * Refresh product rewrite
     *
     * @param Varien_Object $product
     * @param Varien_Object $category
     * @return Mage_Catalog_Model_Url
     */
    protected function _refreshProductRewrite(Varien_Object $product, Varien_Object $category)
    
        //FIX: DONT ADD CATEGORY-PRODUCT-URL - MIGHT HAPPEN IF CATEGORY-PRODUCT-URL EXIST YET FOR THIS PRODUCT
        if (Mage::getStoreConfigFlag('catalog/seo/product_use_categories')) 
            if ($category->getId() && $product->getId()) 
                return $this;
            
        

        parent::_refreshProductRewrite($product, $category);
    

【讨论】:

【参考方案2】:

我建议不要尝试禁用此内置功能,而是 turn on canonical links。如果您有没有此选项的旧版 Magento,请there are other ways to implement it。

但是,如果有人仍然倾向于删除它,他们可能会创建一个扩展 Mage_Catalog_Model_Url 的扩展来执行以下操作:

class My_Catalog_Model_Url extends Mage_Catalog_Model_Url

     public function refreshProductRewrite($productId, $storeId = null)
     
         if (is_null($storeId)) 
             foreach ($this->getStores() as $store) 
                 $this->refreshProductRewrite($productId, $store->getId());
             
             return $this;
         

         $product = $this->getResource()->getProduct($productId, $storeId);
         if ($product) 
             $store = $this->getStores($storeId);
             $storeRootCategoryId = $store->getRootCategoryId();

             // List of categories the product is assigned to, filtered by being within the store's categories root
             // CUSTOMIZATION: Ignore product categories if the 'catalog/seo/product_use_categories' config setting is false.
             if (Mage::getStoreConfigFlag('catalog/seo/product_use_categories', $storeId)) 
                 $categories = $this->getResource()->getCategories($product->getCategoryIds(), $storeId);
              else 
                 $categories = array();
             
             $this->_rewrites = $this->getResource()->prepareRewrites($storeId, '', $productId);

             // Add rewrites for all needed categories
             // If product is assigned to any of store's categories -
             // we also should use store root category to create root product url rewrite
             if (!isset($categories[$storeRootCategoryId])) 
                 $categories[$storeRootCategoryId] = $this->getResource()->getCategory($storeRootCategoryId, $storeId);
             

             // Create product url rewrites
             foreach ($categories as $category) 
                 $this->_refreshProductRewrite($product, $category);
             

             // Remove all other product rewrites created earlier for this store - they're invalid now
             $excludeCategoryIds = array_keys($categories);
             $this->getResource()->clearProductRewrites($productId, $storeId, $excludeCategoryIds);

             unset($categories);
             unset($product);
          else 
             // Product doesn't belong to this store - clear all its url rewrites including root one
             $this->getResource()->clearProductRewrites($productId, $storeId, array());
         

         return $this;
     

【讨论】:

当在管理员中有一个简单的选择来更改以激活规范 url 时,为什么要在模板中使用 hack 呢?系统 >> 配置 >> 目录 >> 搜索引擎优化 @b.enoit.be - 很好。该博客中的解决方案仅适用于没有该选项的旧版本。我已经用另一个博客的链接更新了我的答案,该链接显示了如何使用内置选项(如果可用)启用。 非常有帮助!谢谢你。我想知道规范金属链接的设置是什么。然而,对于我最初的问题,有没有办法做我所问的,只是在原则上? Magento 的核心代码会导致这些链接被创建……这当然可以改变。 @ZacharyBeschler - 一切都可以改变。我用可能会成功的替代解决方案更新了我的答案。

以上是关于防止创建的在产品 URL 中包含类别 URL 键的自动 URL 重写的主要内容,如果未能解决你的问题,请参考以下文章

Composer:在包 URL 中包含版本变量

Django 在我的主 url.py 中包含应用程序 url

Wordpress:在 url 中包含语言变量

当JSON对象URL字段在android studio中包含多个URL时,如何存储来自JSON对象请求的URL?

根据 WCF 服务中发布的 xml 内容识别操作,而不在 Url 中包含操作名称

Spring Boot + Angular 应用程序作为 WAR 部署到 Heroku,抛出 404,除非我在 URL 中包含“index.html”