How should I structure this in Zend Framework?

I'm coming from CodeIgniter, and the terminological overlap between it and other MVC frameworks (Zend in particular) gives me some kind of mental block.

I want my users to visit http://mysite.com/do/this .

I understand that "do" is a controller, and "this" is a function (well, a method) inside that controller.

My site will have common elements like header and sidebar; I understand that they go into the layout that will be included in the final output.

I want / do / this page to display three visual blocks of information (I am deliberately not using the word "modules"). Name them BlockA, BlockB and BlockC. Perhaps it is a list of "new events" and the other is a list of "new messages" and the other is something else. No difference. The trick is that these blocks of information will also appear on other pages on the site - say http://mysite.com/did/that .

Both did and do controllers (and the this and that methods, obviously) will compose BlockA, BlockB, and BlockC differently. Each Controller would have different criteria for what was in these blocks - there may be current information, and other information may be archived from the past.

I want future programmers to be able to easily change the look and feel of BlockA, BlockB and / or BlockC without having to touch the code that populates their data or the code that arranges them on each page.

So, my general opinion is that BlockA, BlockB and BlockC should have their visual layout defined in the view, but that view will not be specifically associated with the "do" or "did" controllers. And the code that fills in these blocks, that is, requests information from the database, selects the bits that should be displayed, as well as what should not be completely in these controllers.

I started down the path of entering logic, that is, assembling what will be displayed in each block, in the Model. I feel like I am on the right track; and do and did controllers can thus invoke block creation code through models. But how (and where) do I abstract the visual of these boxes in such a way that the visuals can also be shared between the two controllers? Can models somehow load the view and output HTML to the controllers (which is awkward)? Or is there a way for Controllers to start the model, get the data to display, and then somehow feed it into a shared / centralized view?

I know how to do this in CodeIgniter. But ... what's the correct architecture to do this using Zend Framework? I am convinced that this is very different from what CodeIgniter will do, and I want to start writing this application with the correct architecture in mind.

+2


source to share


1 answer


One small name: /:controller/:action/*

=> /do/this

= this

is action

(although both a function and a method in a controller, an action is a proper name)

Your blocks sound like "partial views" to me. There are several ways to approach this problem, and depending on how views work or what information they need to know, you will adapt your strategy.

Providing partial data

You want to use this method if you have some view code that you want to use across multiple views. There are two different approaches to using view helpers, Zend_View_Helper::render

or the view Zend_View_Helper_Partial*

helper is render($phtmlfile)

more efficient, the view helper partial($phtmlfile, $module, $params)

clones a new view, prints out all the parameters, and sets the ones you pass. example of their use:

case / list.phtml:

 <?php
    $this->headTitle($this->title);
    // works because our controller set our "cases" property in the view, render
    // keeps our variables
    echo $this->render("case/_caseListTable.phtml");

      

case / view.phtml

 <?php
    $this->headTitle($case->title);
 ?><!--- some view code showing the case -->
 <?php if ($cases = $case->getChildren()): ?>
   <h3>Children</h3>
   <?php echo $this->partial("case/_caseListTable.phtml", "default", array(
          "cases"=>$cases,
         )); ?>
 <?php endif; ?>

      

case / _caseListTable.phtml



// table header stuff
<?php foreach ($this->cases as $case): ?>
   // table rows
<?php endforeach; ?>
// table footer stuff

      

Custom view helpers

Sometimes the controller has no business knowing what information is displayed in the block and preparing it for your view would be silly, at this point you want to create your own view helper. You can easily add them to the global view in application.ini:

resources.view.doctype = "XHTML1_STRICT"
resources.view.helperPath.My_View_Helper = APPLICATION_PATH "/../library/My/View/Helper"

      

I have a tendency to use this method for things that will require additional information from the model not provided by the controller, or blocks of reusable formatting code for the view. A quick example from a project I used: Olympic_View_Helper_Ontap

grabs a beer list and displays it:

class Olympic_View_Helper_Ontap extends Zend_View_Helper_Abstract {
  public function Ontap()
  {
    $view = $this->view;

    $box = Olympic_Db::getInstance()->getTable('box')->getBoxFromName('Draught-Beer');
    if ($box) $menu = $box->getMenu(); else $menu = null;
    $content = "";
    if ($menu)
    {
      $content = "<h1>".$view->escape($menu->title)."</h1>";
      $content .= "<ul>";
      foreach($menu->getItems() as $item) {
        $content .= "<li>".$view->escape($item->name)."</li>";
      }
      $content .= "</ul>";
    }

    return $content;

  }
}

      

Then in my layout:

<?php echo $this->ontap(); ?>

      

Your view helpers can also accept arguments (of course), can call other view helpers (including partial ones). Let's consider their template functions. I like to use them for short tasks that require a lot, such as $this->caseLink($case)

generating a properly formatted tag <a href='/case/2' class='case project'>Project</a>

.

+2


source







All Articles