Controller override and request rewrite in Magento

来源:互联网 发布:阿里云栖大会苏州 编辑:程序博客网 时间:2024/05/18 15:56

Controller override and request rewrite in Magento

There are three ways to override controller in Magento. They fit for various purposes.

The first and easiest way can be used to route the request to morethan one module. When a request arrives on a frontName, it usually isrounted to a module. For example, /cms/page/view is routed to cmsmodule page controller view action. If I have developed a cms relatedmodule called “faq” with a brand new controller “QuestionController”,but I want it share the same cms frontName with cms module, i.e., Iwant /cms/question/any_action be routed to faq module.

It is very easy to achieve by a config.xml like the following:

view sourceprint?
01<config>
02    <frontend>
03        <routers>
04            <cms>
05                <args>
06                    <modules>
07                        <any_name>MyNamespace_Faq</any_name>
08                    </modules>
09                </args>
10            </cms>
11        </routers>
12    </frontend>
13</config>

Strictly speaking, no overriding in above example because it onlyactivates a brand new controller. In a truly overriding example, if Iwant PageController of faq module override PageController in cmsmodule, I can add before=”Mage_Cms” to make sure PageController of faqmodule supersede the same name controller in cms module. The completeconfiguration is shown below:

view sourceprint?
01<config>
02    <frontend>
03        <routers>
04            <cms>
05                <args>
06                    <modules>
07                        <any_name before="Mage_Cms">MyNamespace_Faq</any_name>
08                    </modules>
09                </args>
10            </cms>
11        </routers>
12    </frontend>
13</config>

The second way can be used to mass override controllers.

view sourceprint?
01<config>
02    <global>
03        <rewrite>
04            <any_name>
05                <from><![CDATA[#^/cms/#]]></from>
06                <to>/faq/</to>
07                <complete></complete>
08            </any_name>
09        </rewrite>
10    </global>
11</config>

The above configuration makes all controllers in faq module overridesame name controllers in cms module. In classMage_Core_Controller_Varien_Front, there is

view sourceprint?
1$pathInfo = preg_replace($from, $to, $request->getPathInfo());

doing path info string replacement based on regular expression. Andbecause it is based on regular expression, I can do mass replacement ata time.

The tag flags whether requested path info should beturned into new module path info. In other words, when the requestarrives on /cms/page/view, it is rewritten to /faq/page/view. Without tag, the action layout handle is cms_page_view; with tag, the action layout handle is faq_page_view.

I can use this method to route the request to a brand new controller, i.e.

view sourceprint?
01<config>
02    <global>
03        <rewrite>
04            <any_name>
05                <from><![CDATA[#^/cms/question/#]]></from>
06                <to>/faq/question/</to>
07                <complete></complete>
08            </any_name>
09        </rewrite>
10    </global>
11</config>

Note that cms module does not have question controller, but the above configuration will not cause any error.

The third way can be used to override individual actions.

view sourceprint?
01<config>
02    <global>
03        <routers>
04            <cms>
05                <rewrite>
06                    <page>
07                        <to>faq/question</to>
08                        <override_actions>true</override_actions>
09                        <actions>
10                            <view_action><to>new_module/new_controller/new_action</view_action>
11                        </actions>
12                    </page>
13                </rewrite>
14            </cms>
15        </routers>
16    </global>
17</config>

This method is documented in class Mage_Core_Controller_Varien_Action.

* This will override:
* 1. cms_module/page_controller/view_action to new_module/new_controller/new_action
* 2. all other actions of cms_module/page_controller to faq_module/question_module

It is very handy to precisely control the request rewrite to actionlevel, but it can not route to a brand new controller. The followingcode will cause an error.

view sourceprint?
01<config>
02    <global>
03        <routers>
04            <cms>
05                <rewrite>
06                    <question><!-- Error: cms module does not have question controller -->
07                        <to>faq/question</to>
08                        <override_actions>true</override_actions>
09                        <actions>
10                            <view_action><to>new_module/new_controller/new_action</view_action>
11                        </actions>
12                    </question>
13                </rewrite>
14            </cms>
15        </routers>
16    </global>
17</config>