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 地址重写