Magento URL Rewrite 地址重写

这个将十分的有用, 尤其是在 Magento 创建新的模块(modules)时, 在没有用到 .htaccess 文件的情况下给你的页面原始的 URL 转换成一个有意义的 URL

假设我们现在需要来开发一个模块, 其主要功能是用来显示商品,但商品是属于某一个制造商的, 而制造商是产品的一个属性,由下拉框来选择。 我们现在就用模块名 “manufacturer” 来举例, 如果我们选定一个供应商的时候, 前端的 URL 将会是:

www.your-website.com/manufacturer/index/index/brand/sony

如上所见的就是 Magento 默认的 URL
manufacturer 就是我们的模块名
第一个 index 就是我们的 IndexController
第二个 index 就是我们的 indexAction() 方法
brand / sony 就是我们的请求参数
但是现在我们想要的效果是:

www.your-website.com/manufacturer/sony

这个理想的 URL 如果能和第一个 URL 表达同一个意思, 那将十分的有意义
为了实现该效果, 传统的方法就是利用 .htaccess, 但是在这一章节,我们来看下如何利用 config.xml 来实现

现在让我们来开始我们的旅程

将如下的代码写入 config.xml 文件的 <global> 标签中


<rewrite>
    <fancy_url>
        <from><!--[CDATA[/manufacturer/(.*)/]]--></from>
        <to><!--[CDATA[manufacturer/index/index/manufacturer/$1/]]--></to>
        <complete>1</complete>
    </fancy_url>
</rewrite>

这一段 xml 就是告诉 Magento 去将 /manufacturer/(.*)/ 重写成 manufacturer/index/index/manufacturer/$1/
很显然在 <from> 标签中使用了正则表达式,就是我们想要的效果, 而 <to> 标签里就是转换后实际的 URL
<complete>1</complete> 十分重要, 这个才能让 Magento 在 layout xml 里调用正确的 layout handle, 换句话说, 如果你不写这个 <complete> 标签, 然后当你在 controller 里写入:

$this->loadLayout();
$this->renderLayout();

Magento 不会去读取 <manufacturer_index_index> 相关的节点, 但是会根据你的 URL 读取其他东西

如果你觉得好奇 Magento 是怎么实现这个神奇的功能, 你可以研究下在 Mage_Core_Controller_Varien_Front 类里的 rewrite() 方法


public function rewrite()
{
    $request = $this->getRequest();
    $config = Mage::getConfig()->getNode('global/rewrite');

    if (!$config) {
        return;
    }

    foreach ($config->children() as $rewrite) {
        $from = (string)$rewrite->from;
        $to   = (string)$rewrite->to;
        if (empty($from) || empty($to)) {
            continue;
        }
        $from = $this->_processRewriteUrl($from);
        $to   = $this->_processRewriteUrl($to);

        $pathInfo = preg_replace($from, $to, $request->getPathInfo());

        if (isset($rewrite->complete)) {
            $request->setPathInfo($pathInfo);
        } else {
            $request->rewritePathInfo($pathInfo);
        }
    }
}

你可以看到 Magento 自身的方法里也使用 preg_replace(), 所有任何规则只要符合 preg_replace() 就可以被 Magneto 使用

在正则表达式中,你不可以使用 “{” 和 “}”, 但是在这里,Magento 允许你使用,因为 Magento 在内部处理的时候用到了大括号, 用 route 名字来替换大括号里的内容,见如下代码:

protected function _processRewriteUrl($url)
{
    $startPos = strpos($url, '{');
    if ($startPos!==false) {
        $endPos = strpos($url, '}');
        $routeName = substr($url, $startPos+1, $endPos-$startPos-1);
        $router = $this->getRouterByRoute($routeName);
        if ($router) {
            $fronName = $router->getFrontNameByRoute($routeName);
            $url = str_replace('{'.$routeName.'}', $fronName, $url);
        }
    }
    return $url;
}

 

版权声明:本文内容以盗版加工为主,原创为辅,意在分享,收藏,记录工作中的点点滴滴。不代表任何组织,不代表任何商业机构,也不代表我个人所有想法。
心晴客栈 » Magento URL Rewrite 地址重写

发表回复