0

I'm developing a site using ZF2. One of the section in footer contains tweets. I can fetch tweets but I am not sure how to display them in the layout. I have following ideas but not sure which approach to use

  1. Create a controller plugin and use it on each request.
  2. Create a ViewHelper which fetches the tweets from the ServiceLocator and call the helper in the layout
  3. Attach an event to the MvcEvent::EVENT_RENDER in the module.php which sets the html to a layout variable.

If there is anyother better approach, please let me know.

M Hill
  • 225
  • 2
  • 6
  • I'd choose the 2nd approach. But really, what's 'better' here? Is it 'faster'? Or 'more readable'? Or 'less CPU/memory intense'? Or 'more flexible'? – raina77ow Sep 13 '13 at 16:18
  • better in terms of guidelines and principles. the approach which is breaking as few guidelines as possible. The (possible) drawbacks of each approach are 1. It will make each controller dependent on the base controller, so not flexieble nor extendable nor easily reuseable. 2. I think a view helper should be assisting in the rendering (like url helper) of provided data/information, not providing data of its own. 3. To much dependent on the event driven approach. – M Hill Sep 13 '13 at 16:35

1 Answers1

1

What you are refering to completely is the task of a ViewHelper. So your second approach would be correct. You have two layers here

ServiceLayer - fetching the tweets from a DB / Twitter / DataSource

ViewLayer - displaying whatever the ServiceLayer give you

Now the thing is what do you want to do? Do you want to have a ViewHelper that simply renders a number of given Tweets? Then you'd not need access to the TweetService itself, but rather the given Data. Something like this:

'view_helpers' => array(
    'factories' => array(
        'tweetRenderer' => function ($vhm) {
            $tweetService  = $vhm->getServiceLocator()->get('my-tweetservice');
            $tweetRenderer = new \My\View\Helper\TweetRenderer();
            return $tweetRenderer->render(
                $tweetService->getAllTweets()
            );
        }
    )
)

// in your view then:
echo $this->tweetRenderer();

But most commonly such a thing isn't really that handy. You'd probably want to be able to at least change the username of the Tweets to render. So you'd need to inject the actual TweetService into your ViewHelper and then use the __invokable() function of the ViewHelper to set the parameter for the Renderer:

'view_helpers' => array(
    'factories' => array(
        'tweetRenderer' => function ($vhm) {
            $tweetService  = $vhm->getServiceLocator()->get('my-tweetservice');
            return new \My\View\Helper\TweetService($tweetService);
        }
    )
)

// TweetService.php
public function __construct(TweetServiceInterface $tweetService) {
    $this->tweetService = $tweetService;
}

public function __invoke($username) {
    return $this->render(
        $this->tweetService->fetchTweetsForUser($username)
    ):
}

// in your view then:
echo $this->tweetRenderer('manuakasam');

And that's the basics there are :)

Sam
  • 16,435
  • 6
  • 55
  • 89