4

Is it possible to use the HMVC pattern in Zend Framework? It is implemented in Kohana 3 by default and I really love it, so now I want to use it in Zend Framework.

Edit

I want to make it possible to: 1) include a complete request (like controller/action) inside an other request 2) make a direct call to the controller/action as above

It is not only used for widgets, but I also want to build a page which contains content of other pages...

Edit 2

To be a bit more clear: I do have a page object that contains several elements. These elements can be simple elements (text, image, etc) and special elements, which are controller:action calls. Each page can contain "unlimited" (special) elements. I simply want to loop through these elements, define which kind of element I'm dealing with and add the result of that Element to the content of my view.

Like:

foreach($Page->Elements AS $Element) {
    switch(get_class($Element)) {
        case "Base\TextElement":
            // Add text element to content
            ...
            break;
    case "Base\SpecialElement":
            // Get result of the controller:action call
            break;
        case "Base\ImageElement":
            // Add image element to content
            ...
            break;
        default:
            echo "No case defined for ".get_class($Element);
            die;
    }
}
Rene Terstegen
  • 7,911
  • 18
  • 52
  • 74
  • to some extend you can use the zend view helper http://framework.zend.com/manual/en/zend.view.helpers.html it allows you to call the controller from the view and interact but I'm not an expert on HMVC :) – Hannes Oct 14 '10 at 14:03
  • I want to include the controller_actions in other pages, but also as a main page. For what I know, that is not possible with helpers (except if you want to do it dirty). – Rene Terstegen Oct 14 '10 at 14:11
  • I'm not that familiar with HMVC, but doesn't the action stack essentially do that without much efficiency? This maybe be of interest: http://stackoverflow.com/questions/1558909/best-approach-to-render-site-wide-elements-using-zend-framework – Tim Lytle Oct 14 '10 at 14:17

2 Answers2

3

It all depends, what are you trying to do.

Probably the action stack or action view helpers will do the work for you, but this may be not the best solution, because the dispatch overhead (probably will be removed in ZF2).

The second approach are view helpers with call to the models and actions in the controllers directly. You may use action helpers (and a static call to them) to access controller logic.

Also, see this blog post:

Using Action Helpers To Implement Re-Usable Widgets - phly, boy, phly

takeshin
  • 49,108
  • 32
  • 120
  • 164
  • I'm affraid this is not sufficient. Look at the modification at my original post – Rene Terstegen Oct 19 '10 at 09:15
  • @Stegeman: I haven't looked at Kohana implementation, but in ZF Action stack is what you want. However is should be avoided (already discussed why) and the solution I posted is a recommended replacement for action stack. – takeshin Oct 19 '10 at 20:51
  • I gave it a try, but didn't manage to get it to work. Started an other threat about it: http://stackoverflow.com/questions/3979234/zend-framework-widget-tutorial-question – Rene Terstegen Oct 20 '10 at 14:59
  • If I do understand correctly, I can't decide on page level which "widget" I want to display? – Rene Terstegen Oct 25 '10 at 08:50
  • @Stageman You need to examine the request to determine the module/controller/action or url and add a condition based on it, whether to display or not the widget (this is usually practiced in controller plugins too). – takeshin Oct 25 '10 at 09:28
0

Since what Kohana's HMVC pattern ultimately does is give you a way to service HTTP requests internally, you can create an adapter Zend_Http_Client that does the same thing. I wrote some proof of concept code to do this once; see zend-http-client-adapter-internal.

An example of calling HelloController from IndexController:

class IndexController extends Zend_Controller_Action
{

    public function indexAction()
    {
        $client = new Zend_Http_Client("http://api.local/hello/?name=Clem");

        $client->setAdapter(new Http_Client_Adapter_Internal(
            $this->getFrontController()
        ));

        $response = $client->request();
        echo $response->getBody();
    }

}

As you can see, instead of Kohana's Request::factory($url), you need to construct the client (the api.local hostname is not used I think, but necessary to satisfy some assertion) and then set its adapter. These two steps could obviously be performed by a wrapper function.

mjs
  • 63,493
  • 27
  • 91
  • 122