背景是往一个第三方的搜索插件里面加入filter功能。

首先是路径,插件自己定义了一个router,类似于cms。那首先说说router好了,从入口一路追查的话,会发现最后进入的是Mage_Core_Controller_Varien_Front类下面的dispatch()函数。

   public function dispatch()
{
$request = $this->getRequest(); // If pre-configured, check equality of base URL and requested URL
$this->_checkBaseUrl($request); $request->setPathInfo()->setDispatched(false); $this->_getRequestRewriteController()->rewrite(); Varien_Profiler::start('mage::dispatch::routers_match');
$i = 0;
while (!$request->isDispatched() && $i++ < 100) {
foreach ($this->_routers as $router) {
/** @var $router Mage_Core_Controller_Varien_Router_Abstract */
if ($router->match($request)) {
break;
}
}
}
Varien_Profiler::stop('mage::dispatch::routers_match');
if ($i>100) {
Mage::throwException('Front controller reached 100 router match iterations');
}
// This event gives possibility to launch something before sending output (allow cookie setting)
Mage::dispatchEvent('controller_front_send_response_before', array('front'=>$this));
Varien_Profiler::start('mage::app::dispatch::send_response');
$this->getResponse()->sendResponse();
Varien_Profiler::stop('mage::app::dispatch::send_response');
Mage::dispatchEvent('controller_front_send_response_after', array('front'=>$this));
return $this;
}

前面的代码是把url链接里的各项参数放到request类里面,方便后面调用,从第14行开始,magento会把所有继承自Mage_Core_Controller_Varien_Router_Abstract类的函数拉出来一个个循环match函数,直到找到一个匹配request的。

也就是说假如我想自定义路径,就可以继承Mage_Core_Controller_Varien_Router_Abstract类,然后在match函数里写上自己的路由规则,一旦匹配就跳转到自己想他去的controller类。

不过很显然插件自定义的router并不能很好的完成filter的工作,首先贴上,插件的原来的代码:

  public function match(Zend_Controller_Request_Http $request)
{
$identifier = trim($request->getPathInfo(), '/'); $condition = new Varien_Object(array(
'identifier' => $identifier,
'continue' => true,
)); $identifier = $condition->getIdentifier(); if ($condition->getRedirectUrl()) {
Mage::app()->getFrontController()->getResponse()
->setRedirect($condition->getRedirectUrl())
->sendResponse();
$request->setDispatched(true); return true;
} if (!$condition->getContinue()) {
return false;
} $page = Mage::getModel('searchlandingpage/page')->checkIdentifier($identifier);
//代码原理很简单,对url里的路径拆解,然后查询这个路径是否在自定义的表里面,checkIdentifier()就是sql查询。
if (!$page) {
return false;
} $request->setModuleName('searchlandingpage')
->setControllerName('page')
->setActionName('view')
->setParam('q', $page->getQueryText())
->setParam('id', $page->getId());
//若查询到了就设置request里的各项参数,告诉magento跳转到这里去
$request->setAlias(
Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
$identifier
); return true;
}

修改后:

  public function match(Zend_Controller_Request_Http $request)
{
$helper = Mage::helper('ajaxpriceslider');
$suffix = Mage::getStoreConfig('catalog/seo/category_url_suffix');
$identifier = ltrim($request->getPathInfo(), '/');
$identifier = substr($identifier, 0, strlen($identifier) - strlen($suffix));
$urlSplit = explode($helper->getRoutingSuffix(), $identifier, 2); if(isset($urlSplit[0])){
$cat = $urlSplit[0];
}else{
$cat = $identifier;
}
//这里主要作用是给自定义的路径添加magento的后缀, 如 xxx.html 之类 $condition = new Varien_Object(array(
'identifier' => $cat,
'continue' => true,
)); $cat = $condition->getIdentifier(); if ($condition->getRedirectUrl()) {
Mage::app()->getFrontController()->getResponse()
->setRedirect($condition->getRedirectUrl())
->sendResponse();
$request->setDispatched(true); return true;
} if (!$condition->getContinue()) {
return false;
} $page = Mage::getModel('searchlandingpage/page')->checkIdentifier($cat); if (!$page) {
return false;
} $request->setModuleName('searchlandingpage')
->setControllerName('page')
->setActionName('view')
->setParam('q', $page->getQueryText())
->setParam('id', $page->getId()); $request->setAlias(
Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
$cat.$suffix
);
    // 解析url参数,例如xxx.com/search/chiken_run/shopby/color/brown,green,white-and-green.html的网址,shopby后面的参数会被解析成array('color'=>'brown,green,white-and-green')
$params = explode('/', trim($urlSplit[1], '/'));
$layerParams = array();
$total = count($params);
for ($i = 0; $i < $total - 1; $i++) {
if (isset($params[$i + 1])) {
$layerParams[$params[$i]] = urldecode($params[$i + 1]);
++$i;
}
} $layerParams += $request->getPost();
$request->setParams($layerParams); // 这个生成链接用
Mage::register('layer_params', $layerParams);
$controllerClassName = $this->_validateControllerClassName('Mirasvit_SearchLandingPage', 'page'); $controllerInstance = Mage::getControllerInstance($controllerClassName, $request, $this->getFront()->getResponse());
// 这个是立即执行自己定义的controller类的view函数,不这样做的话,magento会继续加载两个系统router 然后修改了$params,导致我删选数据出问题
$request->setDispatched(true);
$controllerInstance->dispatch('view'); return true;
}

以上路径修改完了,在点击删选的时候 ajax寻址就能寻到了,但是返回的数据还是有问题的,这时候就需要修改 刚刚定义的controller下面的view函数了。

其实修改就一步,将$this->renderLayout();修改成

      if ($this->getRequest()->isAjax()) {
$listing = $this->getLayout()->getBlock('search_result_list')->toHtml();//根据页面的layout不同,这里的getBlock也会不同,下面也是
$layer = $this->getLayout()->getBlock('catalogsearch.leftnav')->toHtml(); // Fix urls that contain '___SID=U'
$urlModel = Mage::getSingleton('core/url');
$listing = $urlModel->sessionUrlVar($listing);
$layer = $urlModel->sessionUrlVar($layer); $response = array(
'listing' => $listing,
'layer' => $layer
); $this->getResponse()->setHeader('Content-Type', 'application/json', true);
$this->getResponse()->setBody(json_encode($response));
} else {
$this->renderLayout();
}

到这一步删选功能正常了,至于他是如何工作的,我有空补上

magento 自定义url路径 和 filter data 小结的更多相关文章

  1. Magento 自定义URL 地址重写 分类分级显示

    我们打算将URL在分类页面和产品页面分别定义为: domain.com/category/分类名.html domain.com/category/子分类名.html domain.com/goods ...

  2. Magento中URL路径的获取

    //获得 media 带 http 的url 地址. Mage::getBaseUrl('media') //获得skin 和js 目录的地址: Mage::getBaseUrl('skin'); M ...

  3. 七天学会ASP.NET MVC (六)——线程问题、异常处理、自定义URL

    本节又带了一些常用的,却很难理解的问题,本节从文件上传功能的实现引出了线程使用,介绍了线程饥饿的解决方法,异常处理方法,了解RouteTable自定义路径 . 系列文章 七天学会ASP.NET MVC ...

  4. 线程问题、异常处理、自定义URL

    线程问题.异常处理.自定义URL   本节又带了一些常用的,却很难理解的问题,本节从文件上传功能的实现引出了线程使用,介绍了线程饥饿的解决方法,异常处理方法,了解RouteTable自定义路径 . 系 ...

  5. 根据url路径获取图片并显示到ListView中

    项目开发中我们需要从网络获取图片显示到控件中,很多开源框架如Picasso可以实现图片下载和缓存功能.这里介绍的是一种简易的网络图片获取方式并把它显示到ListView中. 本案例实现的效果如下: 项 ...

  6. Spring Boot 2.X(十):自定义注册 Servlet、Filter、Listener

    前言 在 Spring Boot 中已经移除了 web.xml 文件,如果需要注册添加 Servlet.Filter.Listener 为 Spring Bean,在 Spring Boot 中有两种 ...

  7. tp5 上传图片(自定义图片路径)

    控制器调用 /** * [goods_addimg 图片上传] * @return [type] [description] */ public function addimg(){ if (requ ...

  8. paip.解决中文url路径的问题图片文件不能显示

    paip.解决中文url路径的问题图片文件不能显示 #现状..中文url路径 图片文件不能显示 <img src="img/QQ截图20140401175433.jpg" w ...

  9. JS分页 + 获取MVC地址栏URL路径的最后参数

    @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&quo ...

随机推荐

  1. UnsatisfiedLinkError: No implementation found for , AndroidStudio使用*.so

    今天工作的时候.发现了一个jni的问题,java.lang.UnsatisfiedLinkError: No implementation found for...... 问题1:后来查了资料后发现. ...

  2. Android SDK更新失败的解决方案(原创)

    笔者在搭建好Android环境后,进行Android的SDK更新下载升级,乌龟的速度,更让人生气的是到了85%的进度时,直接timeout,循环3次无果.查阅相关资料,原来是Google的服务器遭遇了 ...

  3. php composer 相关及版本约束等小技巧

    对于现代语言而言,包管理器基本上是标配.Java有Maven,Python有pip,Ruby有gem,Nodejs有npm.PHP的则是PEAR,不过PEAR坑不少: 依赖处理容易出问题 配置非常复杂 ...

  4. Codility经典算法题之九:MissingInteger

    Task description: This is a demo task. Write a function: that, given an array A of N integers, retur ...

  5. Vijos P1389婚礼上的小杉

    背景 小杉的幻想来到了经典日剧<求婚大作战>的场景里……他正在婚礼上看幻灯片,一边看着可爱的新娘长泽雅美,一边想,如果能再来一次就好了(-.-干嘛幻想这么郁闷的场景……). 小杉身为新一代 ...

  6. 蓝牙协议(bluetooth spec)

    1.概述:   蓝牙协议规范遵循开放系统互连参考模型(OSI/RM),从低到高地定义了蓝牙协议堆栈的各个层次. SIG(Session Initiation Protocol)所定义的蓝牙技术规范的目 ...

  7. bzoj2436: [Noi2011]Noi嘉年华

    我震惊了,我好菜,我是不是该退役(苦逼) 可以先看看代码里的注释 首先我们先考虑一下第一问好了真做起来也就这个能想想了 那么离散化时间是肯定的,看一手范围猜出是二维DP,那对于两个会场,一个放自变量, ...

  8. css盒子模型详解一

    什么是CSS的盒子模式呢?为什么叫它是盒子?先说说我们在网页设计中常听的属性名:内容(content).填充(padding).边框(border).边界(margin), CSS盒子模式都具备这些属 ...

  9. Ubuntu安装mycli,让mysql命令行可以自动提示

    安装mycli 1.确保有安装python 2.确保有安装pip 3.进入su模式,以管理员身份安装 4.安装 pip install -U mycli 5.登录 mycli -u root 很好很强 ...

  10. 移动前端开发之viewport的理解

    在移动设备上进行网页的重构或开发,首先得搞明白的就是移动设备上的viewport了,只有明白了viewport的概念以及弄清楚了跟viewport有关的meta标签的使用,才能更好地让我们的网页适配或 ...