2013-03-29 2 views
1

Похоже, все идет правильно сконфигурированной, и я могу получить вывод, который я хочу, но я предпочел бы не вторя объект макета непосредственно из моего контроллера:Magento Пользовательские маршрутизатор Затерянный Layout Object

Вот что Im работает с config.xml

<config> 
    <modules> 
     <ALS_Bestselling> 
      <version>0.1.0</version> 
     </ALS_Bestselling> 
    </modules> 
    <global> 
     <models> 
      <bestselling> 
       <class>ALS_Bestselling_Model</class> 
      </bestselling> 
     </models> 
     <blocks> 
      <bestselling> 
       <class>ALS_Bestselling_Block</class> 
      </bestselling> 
     </blocks> 
     <helpers> 
      <bestselling> 
       <class>ALS_Bestselling_Helper</class> 
      </bestselling> 
     </helpers> 
    </global> 
    <frontend> 
     <layout> 
      <updates> 
       <als_bestselling> 
        <file>bestselling.xml</file> 
       </als_bestselling> 
      </updates> 
     </layout> 
    </frontend> 
    <default> 
     <web> 
      <routers> 
       <bestselling_router> 
        <area>frontend</area> 
        <class>ALS_Bestselling_Controller_Router</class> 
       </bestselling_router> 
      </routers> 
     </web> 
     <shorturls> 
     </shorturls> 
    </default> 
</config> 

и

#File: Controller/Router.php 

<?php  
class ALS_Bestselling_Controller_Router extends Mage_Core_Controller_Varien_Router_Abstract 
{ 

    private static $_module = 'bestsellers'; 
    private static $_realModule = 'ALS_Bestselling'; 
    private static $_controller = 'index'; 
    private static $_controllerClass = 'ALS_Bestselling_Controller_Index'; 
    private static $_action = 'view'; 


    public function initControllerRouters($observer) 
    { 
     $front = $observer->getEvent()->getFront(); 
     $front->addRouter('bestselling', $this); 
    } 

    public function collectRoutes() 
    { 
     // nothing to do here 
    } 



    public function match(Zend_Controller_Request_Http $request) 
    { 
     $this->_request = $request; 
     $front = $this->getFront(); 
     $identifier = trim($request->getPathInfo(), '/'); 
     if(!substr($identifier,0,strlen('bestsellers')) == 'bestsellers'){ 
      return false; 
     }else{ 
      //$rewrite = Mage::getModel('core/url_rewrite'); 
      $route_params = str_replace ("bestsellers/" , "" , $identifier); 
      $rewrite = Mage::getModel('core/url_rewrite'); 
      $rewrite->setStoreId(1); 
      $rewrite->loadByRequestPath($route_params); 
      $category_route = $rewrite->getIdPath(); 

      //If no route exists for category send to a different router 
      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(); 
     $this->_dispatch(); 
     return true; 
     } 
    } 
    protected function _setRequestRoute() 
    { 
     $this->_request->setModuleName(self::$_module); 
     $this->_request->setControllerName(self::$_controller); 
     $this->_request->setActionName(self::$_action); 
     $this->_request->setControllerModule(self::$_realModule); 

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

и

File: Controller/Index.php 

    class ALS_Bestselling_Controller_Index extends Mage_Core_Controller_Front_Action{ 
    public function viewAction(){ 
      $layout = Mage::app()->getLayout(); 
      $layout->generateXml()->generateBlocks(); 
      $render = $layout->getBlock('root')->toHtml(); 
      echo $render; 
     } 

    } 

Предыдущие работы, но следующее:

$update = $this->getLayout()->getUpdate(); 
$update->addHandle('default'); 
$this->renderLayout(); 

бросает вызов ошибки в функции члена appendBody() на не-объект.

Является ли это тем, как я должен это делать, или есть что-то, отсутствующее в рецепте?

+0

Может быть, некоторые вас интересует, как это может кому-то помочь. Вот как это работает. Представьте, что вы хотите показать некоторую информацию, привязанную к определенной категории, например (лучшие продажи продуктов, faq, обзоры продуктов, топ-рейтинг), но вы хотите иметь уникальный URL-адрес. Вы могли бы сделать что-то вроде категории /? Showme = bestselling Это уродливо.Для целей seo, которые вы, вероятно, захотите сделать/бестселлеры/дополнения/пробиотики Этот маршрутизатор захватывает все после бестселлера и проверяет его, показывает ли его категорию, а затем отправляет идентификатор категории на ваш контроллер. Все еще работаем над решением. – ajameswolf

+0

Что такое номер строки/стек вызовов для 'appendBody' для исключения, отличного от объекта? –

+0

Алан При необходимости я вернусь к своей работе, чтобы ответить на ваш вопрос, но я действительно смог сделать это гораздо более подходящим способом. Дай мне знать. Вот ссылка на сообщение, где я ответил на свой вопрос. http://stackoverflow.com/questions/15691586/force-magento-to-always-use-single-controller-for-module/15709618#15709618 – ajameswolf

ответ

2

Пользовательские классы маршрутизации находятся на грани того, что большинство разработчиков делают с Magento - стандартный подход будет setup a standard module controller with a frontname of bestselling, или создать вашу функцию в не-seo-дружественном виде, а затем создать объект/объект перезаписи для SEO-ify Это.

У меня, однако, есть мягкое пятно для пользовательских объектов маршрутизации, даже если между ними мало возможностей для лучших практик сообщества. Без номера строки, это звучит как исключение

вызов функции члена appendBody() на не-объект

исходит из следующего кода

#File: app/code/core/Mage/Core/Controller/Varien/Action.php 

$this->getResponse()->appendBody($output); 

Учитывая определение на getResponse

public function getResponse() 
{ 
    return $this->_response; 
} 

Это звучит так: ваш объект контроллера не имеет соответствующего набора объектов ответа.

Глядя на ваш контроллер код экземпляра

$controller = Mage::getControllerInstance(self::$_controllerClass, $this->_request, $this->_response); 

Вы ссылки на $this->_response свойство - но ваш класс маршрутизатора и абстрактного класса маршрутизатор не обладают этим свойством. Невозможно сказать, основываясь на том, что вы опубликовали, но это, вероятно, ваша проблема. Посмотрите, как это делает метод сопоставления стандартного маршрутизатора.

#File: app/code/core/Mage/Core/Controller/Varien/Router/Standard.php 
//... 
$controllerInstance = Mage::getControllerInstance($controllerClassName, $request, $front->getResponse()); 

Таким образом, использовать объект переднего контроллера, чтобы захватить объект ответа, передайте, что в метод getCongrollerInstance фабрики, и вы должны быть хорошо идти (или, по крайней мере, на следующей задаче)