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