以下の説明は、通常の方法でフロントネームを定義したことを前提としています:
<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 標準ルーターは URLlanding/cool
を
Mycompany_Landing_CoolController::indexAction()
これは、Magento 標準ルーターがfrontname/controller/action
パターンを使用して URL を処理し、あなたの場合はそれを認識しているためです。
- フロントネームはで、モジュール
landing
にマッピングされていますMycompany_Landing
- コントローラ名は
cool
で、これは次のように変換されますCoolController
- アクション名が欠落しているため、
indexAction
デフォルトで使用されます
ただし、コントローラーではなく、パラメーターになりたいcool
と考えています。
この背後にある理由は、 、landing/cool
などの他に複数のランディング ゾーンが必要だということだと思います。これは、異なるランディング ゾーンごとに 1 つずつ、複数のコントローラーをセットアップする必要があることを意味します。landing/awesome
landing/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 番目の位置で呼び出されます。ルーターは、前の 3 つのルーターのいずれもルート要求に一致しない場合にのみ呼び出されます。
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()
などの他の URL を使用してこれに到達する可能性があるためです。landing
landing/index
landig/index/index
landing/index/index/zone/cool
このような他の URL を SEO ランク付けしたり、検証とサニタイズを 2 回実装したりすることは望ましくないと思いますが、必要ない場合は、そのif
ブロックを削除してください。
これで、 を拡張しindexAction()
て、ランディング ゾーンでやりたいことが何でもできるようになりました。