基于在Magento URL参数加载对象(Loading objects based on URL

2019-09-20 15:18发布

我无法创建我的Magento商店的自定义模块。

我已经成功添加的路由(/登陆),以及显示我的基地布局内的模板内容创建/配置文件。 我现在需要能够超越这一点。

我希望能够从URL中加载一个参数,抢基于该参数的对象,显示基于我的对象的内容的东西。

例如:用户的浏览器domain.com/landing/cool/。 这(希望)将调用登陆控制器。 控制器会在一定程度能够拉动“酷”的参数,并拉凉爽相关联的着陆对象。 然后,我的模板可以得到该对象并显示其内容。

我知道有很多位,但我一直在破解这个我的头一会儿还是一无所获。 Magento的有它的所有类别,项目做到这一点,等没有人有知道我该怎么办呢?

Answer 1:

如果你这样做domain.com/landing/[controller]/cool/[key]/[value],你可以做到这 - $> Request()方法 - > getParam(“[关键]”)来获得[价值的价值]。 然后,您可以设置基于该模板,但我认为这是一个不同的问题。 让我知道如果你还在困惑。



Answer 2:

下面的解释假定您已经定义了frontname通常的方式:

<config>
    <modules>
        <Mycompany_Landing>
            <version>0.1.0</version>
        </Mycompany_Landing>
    </modules>
    <frontend>
        <routers>
            <landing>
                <use>standard</use>
                <args>
                    <module>Mycompany_Landing</module>
                    <frontName>landing</frontName>
                </args>
            </landing>
        </routers>
    </frontend>
</config>

在这种情况下Magento的标准路由器将网址映射landing/cool

Mycompany_Landing_CoolController::indexAction()

这是因为Magento的标准路由器使用处理URL frontname/controller/action模式,在你的情况下,它知道

  • 所述frontname是landing ,其被映射到Mycompany_Landing模块
  • 控制器名称是cool ,这将转化为CoolController
  • 动作名称丢失,这将导致使用indexAction默认

但是你要cool是一个参数 ,而不是一个控制器。

我想这背后的理由是,你想有多个外着陆区landing/cool ,像landing/awesomelanding/insane等。 而这将意味着你必须安装多个控制器,每个不同的着陆区。

一个可能的解决方案,以避免在这种情况下,多个控制器将实现自己的路由器。

实现自己的路由器

为了实现自己的路由器,你需要连接到controller_front_init_routers事件,例如,通过扩展您的app/code/local/Mycompany/Landing/etc/config.xml是这样的:

<config>
    <global>
        <events>
            <controller_front_init_routers>
                <observers>
                    <landing>
                        <class>Mycompany_Landing_Controller_Router</class>
                        <method>controllerFrontInitRouters</method>
                    </landing>
                </observers>
            </controller_front_init_routers>
        </events>
    </global>
</config>

接下来创建一个合适的app/code/local/Mycompany/Landing/Controller/Router.php文件:

 class Mycompany_Landing_Controller_Router extends Mage_Core_Controller_Varien_Router_Abstract { /** * Add own router to Magento router chain * * @param Varien_Event_Observer $oObserver */ public function controllerFrontInitRouters($oObserver) { // Add this router to the current router chain $oObserver ->getEvent() ->getFront() ->addRouter('landing', $this); } /** * Match routes for the landing module * * @param Zend_Controller_Request_Http $oRequest * @return bool */ public function match(Zend_Controller_Request_Http $oRequest) { $sPathInfo = trim($oRequest->getPathInfo(), '/'); $aPathInfo = explode('/', $sPathInfo); // Cancel if the route request is for some other module if ($aPathInfo[0] != 'landing') { return false; } // Cancel if it's not a valid landing zone if (!in_array($aPathInfo[1], array('cool'))) { return false; } // Rewrite the request object $oRequest ->setModuleName('landing') ->setControllerName('index') ->setActionName('index') ->setParam('zone', $aPathInfo[1]) ->setAlias( 'landing_router_rewrite', true ); // Tell Magento that this router can match the request return true; } } 

controllerFrontInitRouters()以上的文件的方法需要照顾自己的路由器将被合并到Magento的路由器链,使它看起来像这样:

Mage_Core_Controller_Varien_Router_Admin
Mage_Core_Controller_Varien_Router_Standard
Mage_Cms_Controller_Router
Mycompany_Landing_Controller_Router
Mage_Core_Controller_Varien_Router_Default

Magento的将循环调度时,这条产业链中给定的顺序。 这意味着,像您这样的定制路由器会一直在最早第4位被调用。 您的路由器才会被调用,如果没有前三个路由器已经可以匹配路由请求。

match()的文件的方法被调用,并检测一个有效的路由(目前landing/cool只),它会改变请求对象,以便Mycompany_Landing_IndexController::indexAction()将被分派,具有参数zone与所述值cool

需要注意的是这个match()是过于简单化。 它不包含消毒等,不要忘记来解决这个^^

最后,创建一个app/code/local/Mycompany/Landing/controllers/IndexController.php文件:

class Mycompany_Landing_IndexController extends Mage_Core_Controller_Front_Action
{

    public function indexAction()
    {

        if (!$this->getRequest()->getAlias('landing_router_rewrite')) {
            $this->_forward('noRoute');
            return;
        }

        $sZone = $this->getRequest()->getParam('zone');

        die(__METHOD__ . ' called with zone = ' . $sZone);

    }

}

首先if该块indexAction取消动作,如果没有landing_route_rewrite在请求对象设置别名( setAlias()在你的路由器的match()方法)。

这样做是因为用户否则也可能达到indexAction()通过使用其他类似的网址landinglanding/indexlandig/index/indexlanding/index/index/zone/cool ,等等。

我猜你不希望有这样的其他URL被搜索引擎优化排名,也没有实施验证和消毒两次,但如果你不需要它,只是删除if块。

现在,您可以延长indexAction()做任何你想用你的着陆区做。



Answer 3:

我正把它多一点在这里了一会儿,但现在这是未来想到的唯一的事情是在爆炸“/”抓住他们。



Answer 4:

下面是我做到了通过JavaScript为我的项目之一:

function populateSelect(url, element, target) {
    var selectedValue = document.getElementById(element);
    var elementValue = selectedValue.options[selectedValue.selectedIndex].value;

    pathArray = url.split( '/' );
    pathArray.shift();
    pathArray.shift();
    pathArray.splice(5,0, element);
    pathArray.splice(6,0, elementValue);
    url = pathArray.join("/");
    url = 'http://' + url;

    new Ajax.Request(url, {
        method:    "POST",
        onSuccess:
            function(transport) {
                var json    = transport.responseText.evalJSON(true);
                var options = '';
                $(target).descendants().each(Element.remove);

                 for (var i = 0; i < json.length; i++) {
                    var opt = document.createElement('option');
                    opt.text = json[i].optionName;
                    opt.value = json[i].optionValue;
                    $(target).options.add(opt);
                }
            }
    });
}


文章来源: Loading objects based on URL parameters in Magento