使用产品商店视图范围的URL密钥的商店开关上的404


13

默认情况下URL Key,产品页面上的“全局范围”。

编辑: 如FlorinelChis所建议,范围可以是“管理”属性中的更改。但是,这破坏了商店视图切换器的行为。

这已在1.7.0.2上经过测试,并带有示例数据并启用了“将商店代码添加到URL”

  1. 编辑产品并为特定的商店视图(法语)设置其他网址
  2. 重新索引
  3. 在英语商店视图中打开网站上的产品页面
  4. 切换为法语:您将拥有页面URL包含 /French/
  5. 切换回英语-> 404页面错误(网址缺少商店代码 /default/

    如何使其与商店视图/语言开关一起正常工作?

细节:

  • 英文网址: /default/sony-vaio-vgn-txn27n-b-11-1-notebook-pc.html
  • 法语的网址: /french/sony-vaio-vgn-txn27n-b-11-1-notebook-pc-french.html

如果我在此页面上的英语网站上-> /default/sony-vaio-vgn-txn27n-b-11-1-notebook-pc.html

然后我改用法语:

我得到了这个URL(商店代码丢失了):
MAGEDOMAIN/sony-vaio-vgn-txn27n-b-11-1-notebook-pc-french.html

所以magento正确地重写了url,但是由于某种原因错过了商店代码

参考:

当然,这与/core/model/store.php和有关/core/model/url/rewrite.php,尤其是与那些方法有关:

Mage_Core_Model_Url_Rewrite::rewrite
Mage_Core_Model_Store::getCurrentUrl

更新

如果您使用的是1.9.1 @Vinai修复程序将无法正常工作,请检查我添加的新答案


您使用的是哪个Magento版本?
FlorinelChis

Magento 1.7.0.2
Fra

蒂姆·我目前正在测试一些答案,并在确认其正常工作后会接受它们。
Fra

Answers:


12

问题是模型Mage_Core_Model_Url_Rewrite_Request(Magento 1.8)和Mage_Core_Model_Url_Rewrite(早期版本)中存在错误。

1.8中的核心代码部分如下所示:

    // Section from Mage_Core_Model_Url_Rewrite_Request::_rewriteDb()

    $fromStore = $this->_request->getQuery('___from_store');
    if (!$this->_rewrite->getId() && $fromStore) {
        $stores = $this->_app->getStores();
        if (!empty($stores[$fromStore])) {
            $store = $stores[$fromStore];
            $fromStoreId = $store->getId();
        } else {
            return false;
        }

该错误:查询参数的值是商店代码,(在我的情况deenfr)。返回的数组的键app->getStores()数字存储ID。那就是为什么if (!empty($stores[$fromStore])) {总是失败。

一旦修复了该错误,稍后便会在同一方法中发现另一个错误(我认为仅在1.8中):

$targetUrl = $this->_request->getBaseUrl() . '/' . $this->_rewrite->getRequestPath();

请求对象的基本url始终是Magento base_url,不带商店代码。使用$currentStore->getBaseUrl()替代方法也可以修复该错误。

解决这两个问题后,语言切换器即可正常工作。这是一个扩展,它完全适用于Magento 1.8(CE):https : //github.com/Vinai/VinaiKopp_StoreUrlRewrites

在Magento 1.7中,问题可能有所不同。我仍然认为我会添加这个答案,以防万一Google将运行1.8或更高版本的其他人带到这里。


您认为我实施的修复程序安全吗?
2013年

老实说,我没有在1.7中研究导致该问题的原因。在未确切了解导致问题的原因的情况下实施修复程序总是有风险的。
Vinai

很抱歉,在2年后重新打开此讨论,但我再次遇到此bug ...在1.9.1上,问题在于if条件$ this-> _ rewrite-> getId()...基本上是针对第二家商店的视图加载重写,因此它不会触发重定向...但是,此重写具有错误的id_path(产品ID为+1),因此它加载404
Fra

4

实际上,如果您正在运行Magento 1.8,请查看Magaito 1.7.0.2上针对此问题的解决方法,以Vinai的详细说明为准:

看起来问题的一部分与请求控制器有关Mage_Core_Controller_Request_Http

如果查看第161行,则出现以下情况:

                elseif ($storeCode !== '') {
                    $this->setActionName('noRoute');
                }

注释掉它可以解决类别/产品页面中的其他商店切换到404错误的问题。

但是由于某种未知的原因,有时在响应URL中会丢失商店代码,但这不再引起问题,因为两个URL现在都可以使用:

  • MAGEDOMAIN / sony-vaio-vgn-txn27n-b-11-1-notebook-pc-french.html
  • MAGEDOMAIN / sony-vaio-vgn-txn27n-b-11-1-notebook-pc.html

我尚不清楚这种情况的评论是否会引起其他问题


我可以确认这对我也有效-每当查看产品时切换到另一种语言,我都会得到404。这已纠正,并且按照您所说的那样,从URL中省略了商店代码,这很奇怪。我无法想象这是最好的解决方案,因为不能像这样编辑核心控制器那么好,我想知道您是否最终找到了另一个解决方案?
waffl

您不需要编辑任何核心文件,您可以创建自己的模块并重写该类/方法。
法兰克福机场

1
Mage_Core_Controller_Request_Http无法在模块中重写。
benmarks 2013年

4

Magento 1.9.1的一些更新信息

@Vinai指出的错误无论如何仍在此版本中得以解决,原因是该功能仍然被破坏(对于可配置产品)

问题真正的问题可能在这里,Mage_Catalog_Model_Resource_Url但是我没有时间,也不想触及核心的如此微妙的部分。

解决方法的说明:

入口始终是此类Mage_Core_Model_Url_Rewrite_Request ,尤其是方法_rewriteDb()

如何_rewriteDb()工作:

  1. 首先,它尝试加载当前商店的请求

(139): $this->_rewrite->loadByRequestPath($requestCases);

  1. 然后,如果我找不到它(没有id)并有一个___from_store参数

(142): if (!$this->_rewrite->getId() && $fromStore) {

  1. 尝试为加载重写___from_store

(152): $this->_rewrite->setStoreId($fromStoreId)->loadByRequestPath($requestCases);

  1. 如果找到它,则使用id_path来为当前商店加载一个:

(159): $this->_rewrite->setStoreId($currentStore->getId())->loadByIdPath($this->_rewrite->getIdPath());

一切看起来不错,但是url_rewrite数据中存在问题,因此索引功能也存在问题(至少对于可配置产品而言):

  • 即使我们要切换存储,并且新存储具有不同的url,也会加载第139行的重写。

问题在于此重写指向错误的位置id_path(而不是指向可配置的产品ID,而是指向其简单产品ID之一)

现在一种解决方法是删除!$this->_rewrite->getId()条件,因此magento总是尝试在有$fromstore参数的情况下找到重定向

  • 最好的办法是修复catalog_url索引并删除它创建的错误重写。

这里是快速解决方法的代码(您将需要创建一个模块并Mage_Core_Model_Url_Rewrite_Request自行重写类):

protected function _rewriteDb()
    {
        if (null === $this->_rewrite->getStoreId() || false === $this->_rewrite->getStoreId()) {
            $this->_rewrite->setStoreId($this->_app->getStore()->getId());
        }

        $requestCases = $this->_getRequestCases();
        $fromStore = $this->_request->getQuery('___from_store');

        if ($fromStore) {
            $stores = $this->_app->getStores(false, true);
            if (!empty($stores[$fromStore])) {
                /** @var $store Mage_Core_Model_Store */
                $store = $stores[$fromStore];
                $fromStoreId = $store->getId();
            } else {
                return parent::_rewriteDb();
            }

            $this->_rewrite->setStoreId($fromStoreId)->loadByRequestPath($requestCases);
            if (!$this->_rewrite->getId()) {
                return parent::_rewriteDb();
            }

            // Load rewrite by id_path
            $currentStore = $this->_app->getStore();
            $this->_rewrite->setStoreId($currentStore->getId())->loadByIdPath($this->_rewrite->getIdPath());

            $this->_setStoreCodeCookie($currentStore->getCode());

            $targetUrl = $currentStore->getBaseUrl() . $this->_rewrite->getRequestPath();
            $this->_sendRedirectHeaders($targetUrl, true);
        }

        if (!$this->_rewrite->getId()) {
            return parent::_rewriteDb();
        }

        $this->_request->setAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
            $this->_rewrite->getRequestPath());
        $this->_processRedirectOptions();

        return true;
    }

3

URL键是一个属性。您可以从以下目录进行编辑:目录->属性->管理属性。搜索url_key并单击它。 编辑url_key属性

更改范围并保存。

现在,您可以在每个商店视图上为产品使用不同的URL密钥。


我已经更新的问题,你的答案是好的,但它不工作
法兰克福机场

当您切换商店时,您应该登陆该商店首页而不是产品页面。
FlorinelChis

您登陆的地方与出发地相同:如果您位于类别页面上,则应该以不同的语言登陆同一页面
Fra

1

因此,您想更改每个商店视图的URL吗?

目前,您在法国商店的得分范围内修改了商品URL,使其与英语商店有所不同?当您在两者之间切换时,会得到404。这是预期的行为。

Magento不会为其他商店视图存储不同的URL重写。因此,当您点击/french/product1法国商店时,URL将在表中匹配并加载。但是,当您在英语商店中找到它时,将没有匹配项,因此会出现404。

听起来您需要的只是“将商店代码添加到URL”-这将使您的URL密钥保持单独,而在所有相应的URL前面加上商店代码。然后,这将使您的商店切换台起作用。


1
如Vinai所证实,这是一个错误
Fra
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.