4

I have a sidebar which appears on every page. The first elements of the sidebar are either a) a login form, or b) details of the current user, (depending on whether the user is logged in or not).

I have read up on a few ways to accomplish this and am planning to initialise a sidebar placeholder in the bootstrap.

When it comes to appending the user details, or the login form, to the sidebar, should I be doing this from predispatch in an Action Helper? Or from predispatch in a controller plugin? Why?

Thanks!

DatsunBing
  • 8,684
  • 17
  • 87
  • 172

4 Answers4

1

I recommend reading Using Action Helpers To Implement Re-Usable Widgets by Matthew Weier O'Phinney (ZF Lead).

In his example he uses public function preDispatch() in an Action Helper to create a reusable Login/User-Widget.

Benjamin Cremer
  • 4,842
  • 1
  • 24
  • 30
0

I would use the ActionStack Action Helper to stack a call to the user controller. Stacking means, when you're done with this current action, let's call a new one before going to layout rendering.

This User controller would then be able to decide (based on Auth stored in registry) which content it should produce/take from cache). And this user controller action would use $this->_helper->viewRenderer->setResponseSegment('myusersidebar'); to let the main Zend_Layout simply call <?= $this->myusersidebar ?> to echo the block.

So this not a controller plugin (except Action Stack is a controller plugin), not a controller predispatch, but simply the way of looping in Zend MVC stack by stacking several actions and rendering the layout at the end.

The action stacking is in fact related to layout composition and should be avoided for special requests (like ajax requests, they certainly do not need your user block). So you can either decide to do delay this process of stacking layout blocks on each Actions (and avoid stacking it for ajax actions), or add some code to remove the actions you want to stack when the Ajax Context loads (like the way Zend_Layout is disabled in AjaxContext).

The problem with a 'simple' predispatch treatment is that you may execute code to prepare your html block for requests that won't need this block (ajax requests, pdf requests, etc).

regilero
  • 29,806
  • 6
  • 60
  • 99
  • 2
    Some people think that the [Zend Framework Actionstack is Evil](http://www.rmauger.co.uk/2009/03/why-the-zend-framework-actionstack-is-evil/). Note that the commenters there include Matthew Weier O'Phinney, who seems to regret including it in the framework. – David Weinraub May 20 '11 at 04:21
  • interesting reading, and i agree the action view helper is really bad. But I disagree with the complexity and I really believe this is a smart composition design. I like the fact acl check can differs for different blocks of my page, and I like the fact I can use different caching policies for each calls on the MVC loop. Now if they don't want it anymore we'll have to think differently... – regilero May 20 '11 at 10:07
  • @David Weinraub: one point I forgot to mention, the actionStack way of managing layout composition has 1 major advantage to me, it's really easy to alter it in an ajax-composition layout or an ESI (varnish-ESI) way of managing it, individual controller/actions already exists. – regilero May 23 '11 at 12:38
  • @regliero: I confess that I have not used the action stack, largely scared off by accusations of evil. But given your points, I might need to look again, at least for contexts such as those you have identified where it can be useful - and where there is minimal risk of compromised morality. ;-) Thanks and cheers! – David Weinraub May 23 '11 at 16:15
0

I actually believe doing it like that is not DRY. The user object would already be in the ZF app (Zend_Auth), thus additional duplicate logic is unnecessary IMO. All that's left is for your views to decide what to display based on the object's status.

Oh, I highly recommend a partial for this.

e.g. in your layout:

<?= $this->partial('userSidebar.phtml'); ?>

and then in your partial /application/layouts/userSidebar.phtml:

<div id="sidebar">
<?php if Zend_Auth::getInstance()->hasIdentity() : ?>
  <?php $user = Zend_Auth::getInstance()->getIdentity() ?>
  // do some user profiling stuffies
  // if you need more information you should rather associate the user with those entities (else consider retrieving here or passing it as a parameter in the partial method)
<?php else : ?>
  // not logged in
  // do some login/registering stuffies
<?php endif ?>
</div>
Tjorriemorrie
  • 16,818
  • 20
  • 89
  • 131
0

I would use view helpers. This is from my first Zend project. It draws a link depends on whether a user is admin.

<?php
class TBB_View_Helper_PanelLink extends Zend_View_Helper_Abstract
{
    public function panelLink($moduleName = 'customer')
    {
        $panelLink = "";
        $auth = Zend_Auth::getInstance();
        if($auth->hasIdentity()) {
            $identity = $auth->getIdentity();
            $username = $identity->username;
            $userModel = new TBB_Model_Users();
            $userID = $userModel->getUserIDByUsername($username);
            if($userModel->isAdminUser($userID)) {
                if($moduleName == 'customer') {
                    $panelLink =  '<a class="span-4" href="admin/">Admin Panel</a>';
                } else if($moduleName == 'admin') {
                    $panelLink = '<a class="span-4" href="/">Homepage</a>';
                }
            }
        }
        return $panelLink;
    }
}
emeraldhieu
  • 9,380
  • 19
  • 81
  • 139