2

最終的な結果として、 http://www.mysite.com/frontname/something/somethingにアクセスできます。

フロントネームの後のすべてをキャプチャし、それを使用してフックを追加し、データを設定します。これは、カテゴリの動作と同様に機能しますが、そのカテゴリに関連するレイアウトで別のブロックを呼び出すことができるように、私のフロントネームが URL の前に追加されます。

これがすべて理解された後に他の誰かを助ける場合は、_call メソッドを使用してすべてのリクエストを処理します: magento コントローラーの動的ルーター名

これを行うためのより良い方法があれば、すべて耳にします。

4

2 に答える 2

1

デフォルト ルーターに追加して使用するカスタムルーターを作成する必要があります。config に新しいルーターを追加するには、次の XML を使用します。

<default>
    <web>
        <routers>
            <arbitrary_name>
                <area>frontend</area>
                <class>Your_Module_Controller_Router_Something</class>
            </arbitrary_name>
        </routers>
    </web>
    <shorturls>
    </shorturls>
</default>

ルーターは次のようになります。

class Your_Module_Controller_Router_Something extends Mage_Core_Controller_Varien_Router_Abstract
{
    private static $_module = 'your_module';
    private static $_realModule = 'Your_Module';
    private static $_controller = 'your_controller';
    private static $_controllerClass = 'Your_Module_ControllerClassName';
    private static $_action = 'your_action';

    /**
     * @var Zend_Controller_Request_Http
     */
    protected $_request;

    /**
     * Front controller looks for collectRoutes() although it is not defined
     * in abstract router class!
     * 
     * (non-PHPdoc)
     * @see Mage_Core_Controller_Varien_Router_Standard::collectRoutes()
     */
    public function collectRoutes()
    {
        // nothing to do here
    }

    /* (non-PHPdoc)
     * @see Mage_Core_Controller_Varien_Router_Abstract::match()
     */
    public function match(Zend_Controller_Request_Http $request)
    {
        $this->_request = $request;

        // here you will have to implement your matching:
        // - detect if the request should be matched by this router
        //   (i.e. check for "frontname" after base url)
        // - return false if not

        // - otherwise:
        $this->_setRequestRoute();
        $this->_dispatch();
        return true;
    }
    /**
     * @return void
     */
    protected function _setRequestRoute()
    {
        $this->_request->setModuleName(self::$_module);
        $this->_request->setControllerName(self::$_controller);
        $this->_request->setActionName(self::$_action);
        $this->_request->setControllerModule(self::$_realModule);

    }
    /**
     * @return void
     */
    protected function _dispatch()
    {
        $this->_request->setDispatched(true);
        $controller = Mage::getControllerInstance(
            self::$_controllerClass, $this->_request, $this->_response
        );
        $controller->dispatch(self::$_action);
    }
}

重要なメソッドはmatch()、すべてのリクエストに対して呼び出されるメソッドであり、ルーターがリクエストを担当しているかどうかを判断し、担当している場合はディスパッチする必要があります。このルーターは、常に同じコントローラー アクションをディスパッチしますyour_controller/your_action

また、URL に基づいていくつかのパラメーターを使用できるようにすることもできます。$this->_request->setParam(key, value)

于 2013-03-28T23:23:48.293 に答える
0

上記のコードはある程度機能するため、もう少し理解と説明が必要です。過去10時間ほどこれを使ってツールを使った後、私が思いついたのは次のとおりです。

ファイル:config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <AJW_Bestselling>
            <version>1.6.0.0.1</version>
        </AJW_Bestselling>
    </modules>
    <frontend>
        <routers>
            <bestselling>
                <use>standard</use>
                <args>
                    <module>AJW_Bestselling</module>
                    <frontName>bestsellers</frontName>
                </args>
            </bestselling>
        </routers>
        <layout>
            <updates>
                <bestselling>
                    <file>bestselling.xml</file>
                </bestselling>
            </updates>
        </layout>
    </frontend>
    <global>
        <events>
            <controller_front_init_routers>
                <observers>
                    <bestselling>
                        <class>AJW_Bestselling_Controller_Router</class>
                        <method>initControllerRouters</method>
                    </bestselling>
                </observers>
            </controller_front_init_routers>
        </events>
        <models>
            <bestselling>
                <class>AJW_Bestselling_Model</class>
            </bestselling>
        </models>
        <blocks>
            <bestselling>
                <class>AJW_Bestselling_Block</class>
            </bestselling>
        </blocks>
        <helpers>
            <bestselling>
                <class>AJW_Bestselling_Helper</class>
            </bestselling>
        </helpers>
    </global>

ファイル:Controller/Router.php

<?php

class AJW_Bestselling_Controller_Router extends Mage_Core_Controller_Varien_Router_Abstract
{
    private static $_module = 'bestsellers';
    private static $_realModule = 'AJW_Bestselling';
    private static $_controller = 'index';
    private static $_controllerClass = 'AJW_Bestselling_Controller_Index';
    private static $_action = 'view';


    public function initControllerRouters($observer)
    {
        $front = $observer->getEvent()->getFront();

        $front->addRouter('bestselling', $this);
    }

    public function match(Zend_Controller_Request_Http $request)
    {
        $this->_request = $request;
        $identifier = trim($request->getPathInfo(), '/');

        //If Magento Is Not Installed Reroute To Installer
        if (!Mage::isInstalled()) {
            Mage::app()->getFrontController()->getResponse()
                ->setRedirect(Mage::getUrl('install'))
                ->sendResponse();
            exit;
        }
        //If we dont match our router then let another router take over
        if(!substr($identifier,0,strlen('bestsellers')) == 'bestsellers'){
            return false;
        }
        //If we do match the our router then lets add some data and dispatch our 

controller
            else{
            $route_params = str_replace ( "bestsellers/" , "" , $identifier );
            $rewrite = Mage::getModel('core/url_rewrite');
            $rewrite->setStoreId(1);
            $rewrite->loadByRequestPath($route_params);
            $category_route = $rewrite->getIdPath();
                //Check to see if the route exists before we do anything else
                if(!$category_route != ""){
                    return false;
                }//Otherwise send the parameters to the request
                else{
                    $id = str_replace ( "category/" , "" , $category_route );
                    $this->_request->setParam('id',$id);
                }

            }
            $this->_setRequestRoute();
            return true;
        }

        protected function _setRequestRoute()
        {
            $this->_request->setModuleName(self::$_module)
                ->setControllerName(self::$_controller)
                ->setActionName(self::$_action)
                ->setControllerModule(self::$_realModule);
            return true;

        }


    }

ファイル:controllers/IndexController.php

class AJW_Bestselling_IndexController extends Mage_Core_Controller_Front_Action{

    public function indexAction(){

        echo "This is the index controller";
        die();
    }

    public function viewAction(){
        $this->loadLayout();
        $this->renderLayout();
    }
}

mysite.com/bestsellers/ にアクセスすると、ルーターがインデックス コントローラーをロードします。ただし、bestsellers/some/category/url.html にアクセスすると、viewAction が起動され、コントローラが使用するためにカテゴリ ID が送信されます。

この背後にある概念は、.com の後の URL の最初の部分に基づいて、各カテゴリにコンテンツを表示する機能です。いくつかのアイデアは、ベストセラー、最も推奨される、トップレビュー、カテゴリの質問など..特定のカテゴリとの多対一 (または多) の関係。

また、AJW_Bestselling_Controller_Router のパラメーターを条件付きで設定することにより、この同じモジュールを複数のモジュールのルーターとして使用できる可能性があることに注意してください。

于 2013-03-29T18:52:29.170 に答える