1

I am new to Zend Framework and would like advice on how best to loop through database data to generate a list of links. My understanding is that the Model should contain most of the application logic with the controllers and views being as light as possible.

I am querying the db to get a set of records and I want to loop through them and generate HTML links. Psuedocode below.

CONTROLLER:

$this->view->myList = MODEL->generateHtml();

MODEL:

function generateHtml() {
    query db

    loop through record set

    build a string of html within loop including links

    return string to controller

}

VIEW:

echo $this->myList;

This seems to put the logic in the model and leave the controller light and the view only for rendering.

One problem I have is that I want to use $this->view->url to generate routing links in the html I output but cannot do that in the model. The reading I have done online suggests that you should not be building html in the model. I can generate an array of the required data in the model and return that and then loop through that in either the controller or the view to generate the html but am unsure as to what is the correct approach and would appreciate some advice.

Thanks for any help given.


NEW PROBLEM - UPDATED CODE:

Hi again....have tired suggestion below but have a different issue now.

My code is now:

MODEL:

not used for this test. will return array similar to array created in controller.

CONTROLLER:

    $aStoryList = array( 
        array(
           'headline' => 'Headline 1', 
           'story' => 'Story 1' 
        ), 
        array(
           'headline' => 'Headline 2',
           'story' => 'Story 2'
        )
    );
    $this->view->aStoryList = $aStoryList;

VIEW:

echo $this->partialLoop('partials/storyList.phtml', $this->aStoryList);

storyList.phtml:

echo "<br />" . $this->headline . $this->story;

I have placed the partial thus....

views/partials/storyList.phtml

This placement and the path used in the view are derived from the answer to this stackoverflow question - Where do I save partial (views) in Zend Framework, to be accessible for all Views in my App?

When I run this I get the following error

Message: script 'partials/storyList.phtml' not found in path (/home/sites/xxxxx.com/public_html/xxxxxxx/application/views/scripts/)

Pulling my hair out now!

Community
  • 1
  • 1
slip0000
  • 17
  • 5

1 Answers1

2

The model should be used to pull data from your data source, but should not be generating any HTML markup. Save the HTML generation for the view. The controller will be the glue between the model and view; that is the controller will do the work to fetch the data and hand it off to the view where the output is generated.

In your particular case, the PartialLoop View Helper should be useful for creating markup in a loop.

I'd propose the following Pseudocode instead of what you had posted above:

CONTROLLER:

$this->view->myList = MODEL->getListOfItems();  // return an array of data

MODEL:

function getListOfItems() {
    $results = array(); // array of data to return

    // query db

    // loop over result set
    foreach($result as $row) {
        $results[] = $row;
    }

    return $results;
}

VIEW:

<?php echo $this->partialLoop('myList.phtml', $this->myList);

myList.phtml View Partial:

<tr>
    <td><a href="<?php echo $this->url(array('id' => $this->id))"><?php echo $this->username ?></a></td>
    <td><?php echo $this->firstName ?> <?php echo $this->lastName ?></td>
    <td><?php echo $this->email ?></td>
</tr>

To summarize:

  • Controller queries model for data
  • Model returns an array of results
  • Controller passes array directly to view
  • View calls partialLoop helper and passes the array from the model
  • partialLoop helper iterates over all of the results, passing them one at a time to myList.phtml (note how the variable scope becomes local to the view partial).

My example assumes the array returned by the model contains the keys id, username, firstName, lastName.

Hope that helps, feel free to comment if you have any questions.

drew010
  • 68,777
  • 11
  • 134
  • 162
  • Can you call a `partialLoop` inside another `partialLoop`? Another thing (I'm not sure of it though) isn't using the partial view helper bad for performance and one should use `render` instead? – Songo Jun 04 '12 at 20:56
  • Hi drew - thanks very much for taking the time to write a detailed and informative response. I had not heard of the partialLoop view helper but will take a look. Looking at your pseudocode it looks like exactly what I want. Really appreciate your effort - cheers ( stackoverflow won't let me vote up your answer as I am new but really do appreciate your efforts) – slip0000 Jun 04 '12 at 21:28
  • 1
    @Songo From looking at the code for `partial` and `partialLoop`, I don't see any reason why you couldn't call a `partialLoop` from within another `partialLoop` (as long as you don't get yourself into a recursive hole by passing the same data). There is probably some performance hit as `partialLoop` calls `partial` which `clone`s your view object, clears its vars, and assigns the partial vars to it and then calls `render()` on the cloned view and returns the content. It might be interesting to see some benchmarks on comparing partialLoop vs loop and view render. – drew010 Jun 04 '12 at 22:11
  • Just a very little improvement. The query to the database should ideally return an array already, so no additional looping inside of PHP is necessary to create the array. – Sam Jun 05 '12 at 05:06
  • Hi again - I have edited my question above to illustrate a new path related problem I am having. I'm sure the partialLoop answer will work if I can only get it to run. Thanks to anyone who can advise me. – slip0000 Jun 05 '12 at 07:06
  • @slip0000 The location that it is looking for the `partials` directory is in `/home/sites/xxxxx.com/public_html/xxxxxxx/application/views/scripts/`. So if you create `/home/sites/xxxxx.com/public_html/xxxxxxx/application/views/scripts/partials/storyList.phtml` it should function correctly. – drew010 Jun 05 '12 at 16:24