【问题标题】:Make routing to my custom module in magento在 magento 中路由到我的自定义模块
【发布时间】:2014-08-28 22:18:12
【问题描述】:

我在 magento 中制作了一个带有布局的自定义模块。它显示了特定客户群的客户信息。

它的网址是

www.mysite.com/profile/index/index/mayank

profile 是我的模块名称,index 是控制器名称,第二个索引是索引控制器的方法,而 mayank 是客户的用户名(唯一字段或属性)。

我需要的是。

使这个网址像这样:-

 www.mysite.com/mayank

【问题讨论】:

  • 默认情况下,您不能这样做。但是如果你用myank替换你的模块名,你可以轻松实现它
  • 请重新考虑较短的 URL。客户可以注册用户名“admin”或任何其他模块名称并立即破坏您的商店。
  • @clockworkgeek 你是对的。无论如何我们可以这样做'如果没有找到路线,那么magento会调用我们模块的控制器,因为它现在显示404页面。'?我不是magento专家。我是初学者。

标签: php magento routing


【解决方案1】:

首先,Magento URL 倾向于将字段名称放在值之前。所以我希望长 URL 实际上看起来像这样:

www.mysite.com/profile/index/index/name/mayank

这将允许在控制器中进行整洁的检索,

public function indexAction() {
    $name = $this->getRequest()->get('name');
}

“无论如何,我们是否可以像'如果找不到路由,那么 magento 会调用我们模块的控制器......?”

我有wrestled with routers before,在我看来,除非绝对必要,否则它们是不必要的。当可能的 URL 数量有限时,提前save a rewrite 会更容易。执行此操作的最佳时间是用户名更改时。

要监听更改,请将其添加到模块的config.xml:

<global>
    <events>
        <customer_save_after>
            <observers>
                <mayank_profile>
                    <type>singleton</type>
                    <class>mayank_profile/observer</class>
                    <method>customerSaveAfter</method>
                </mayank_profile>
            </observers>
        </customer_save_after>
        <customer_delete_after>
            <observers>
                <mayank_profile>
                    <type>singleton</type>
                    <class>mayank_profile/observer</class>
                    <method>customerDeleteAfter</method>
                </mayank_profile>
            </observers>
        </customer_delete_after>
    </events>
</global>

在模块的Model 文件夹中创建Observer.php:

class Mayank_Profile_Model_Observer {
    public function customerSaveAfter(Varien_Event_Observer $observer) {
        $customer = $observer->getCustomer();
        // username is not a standard attribute, hopefully you have created it
        if ($customer->dataHasChangedFor('username')) {
            $this->remove($customer->getOrigData('username'));
            $this->add($customer->getData('username'));
        }
    }

    public function customerDeleteAfter(Varien_Event_Observer $observer) {
        $customer = $observer->getCustomer();
        $this->remove($customer->getOrigData('username'));
    }

    protected function remove($username) {
        // this does nothing if rewrite doesn't exist
        Mage::getModel('core/url_rewrite')
            ->loadByIdPath('profile/'.$username);
            ->delete();
    }

    protected function add($username) {
        if ($this->isValidUsername($username)) {
            $storeId = Mage::app()->getDefaultStoreView()->getId();

            Mage::getModel('core/url_rewrite')
                ->setIsSystem(0)
                ->setStoreId($storeId)
                // IdPath is used by remove() function
                ->setIdPath('profile/'.$username)
                // TargetPath is your controller/action
                ->setTargetPath('profile/index/index/name/'.$username)
                // RequestPath is what the browser sees
                ->setRequestPath($username)
                ->save();
        }
    }

    protected function isValidUsername($username) {
        // feel free to add more checks here
        // start with existing rewrites
        $rewrite = Mage::getModel('core/url_rewrite')
            ->loadByRequestPath($username);
        if (!$rewrite->isObjectNew()) {
            return false;
        }

        // scan known frontNames
        $frontNames = Mage::getConfig()->getXPath('*/routers/*/args/frontName');
        foreach ($frontNames as $name) {
            if ($username == (string) $name) {
                return false;
            }
        }

        return true;
    }
}

这是一项相当多的工作,但这里的优点是以下代码正确查找之前保存为“RequestPath”的路径:

echo Mage::getUrl('profile', array(
    'name' => $username,
    '_use_rewrite' => true
));

这是一种更简单的方法,仅适用于不能与其他模块冲突的 URL。将此添加到您的config.xml:

<global>
    <rewrite>
        <mayank_profile>
            <from><![CDATA[#^/profile/#]]></from>
            <to><![CDATA[/profile/index/index/name/]]></to>
            <complete>1</complete>
        </mayank_profile>
    </rewrite>
</global>

在输出 URL 时,您需要自己连接路径。例如

echo Mage::getUrl('', array(
    // Use _direct here to avoid a trailing solidus
    '_direct' => 'profile/' . $username
));

【讨论】:

  • 它的正确答案但看起来我需要将所有管理员、客户或产品名称等列入黑名单,以免用作用户名。所以我应该更好地说服我的客户使用 www.sitename.com/profile/username。我说的对吗?
  • 我希望isValidUsername()函数能覆盖大部分黑名单,虽然我没有测试过。无法保证是否会成功阻止所有未来的合法 URL。例如,我刚刚意识到它不考虑 CMS 页面。我已更新我的答案以处理 www.sitename.com/profile/username 格式。
  • 嗨,当使用带有“FLAG_NO_DISPATCH”的 setFlag 方法的用户名无效时,我试图从观察者返回错误消息,但我无法获取控制器对象。你能帮帮我吗?
  • 这是一个单独的问题。开始一个新问题并更详细地解释。
【解决方案2】:

您可以尝试通过htaccess rewriterule 解决此问题

或者

在controller_action_layout_load_before 上创建一个观察者并获取REQUEST_URI 并将其用于您的案例。

祝你好运

【讨论】:

  • 如果你能详细告诉我如何使用观察者解决这个问题,那就太好了。我是 magento 的初学者。
猜你喜欢
  • 2017-06-15
  • 1970-01-01
  • 2016-09-05
  • 1970-01-01
  • 1970-01-01
  • 2011-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多