views:

1978

answers:

5

I'm working on building up an interface that I want to function as a "tabbed browsing" sort of function. Each of these tabs has already been written as an action and the tabbed interface works fine as links to the individual tabs. I decided to try writing the "index" page for this controller - putting the content of all the tabs into hidden divs and swapping between them with jQuery, but once I started to use the action view helper - I ran into a lot of people saying that its bad practice. (see this article)

Some of these actions build up forms - grab some data from the model, etc to display. I want each of the actions to continue to function on their own (some parse forms as well).

Browsing to /item should give you the tabbed menu, plus all of the div's contents in a hidden tag - where /item/tab2 is a specific action (form submit for instance).

Another complication/caveat - Some of the actions will throw Access Exceptions if the user doesn't have access to that "tab". I'd prefer not to build access checking into the system twice (thus showing a tab with empty content).

I'm just trying to figure out what the best practice is to handle this sort of thing, and I thought that the action helper might be it. If I try to use View Helpers - I start wondering if that is the right place to assemble a Zend_Form.

Does anyone have any suggestions on the "proper" way to work around not using the Zend_View_Helper_Action ?

A: 

Whenever I've had to work around an issue I couldn't directly address using a native Zend Framework component, I've reached for my trusty solve all: JavaScript. I suggest you take a look at the jQuery tabs plugin.

jakemcgraw
+1  A: 

If you're not generating the tab/tab panes from existing markup, and you're loading the content on demand, then you simply must check whether the user has permission to access the tab before displaying the tab itself, and again when attempting to load the tab's content.

Checking whether the user has these access permissions should be an acceptable mode of operation and should not be expensive to perform.

If these actions produce content that works in some standalone page, in addition to the tabs, then the Action view helper is the corrent way to proceed. Simply perform the same ACL (or other) check performed in the action when generating the tab.

David Caunt
+1  A: 

I'm not entirely sure what your exact problem is, however you can disable the layout:

$this->_helper->layout->disableLayout();

Then the requested Action will just display it's view script, which you can load into the tab.

Any authorisation code you have will function as normal and you can display the requested view script for the Action, or not depending on if they have access.

firecall
A: 

You can catch any access exceptions by using a try/catch block:

try { // action throwing exceptions } catch (Exception $e) { // catch silently }
sandstrom
Actually - lots of other things get messed up when doing this with the action view helper. I submitted a bug fix for it in JIRA
gnarf
+2  A: 

The Correct way to work around the action view helper, as I stated in the article you cited, is to create partials which access the model directly to fetch the data they need. This can be through a view helper (you make this yourself ;)) if this would involve a lot of logic in your view.

The action view helper is plagued with more than just performance issues, but also creates horrendous debugging nightmares, and if you need it, then your application is probably not following MVC, and therefore, you are using the controller for reuse, instead of the model, which is the patterns intention.

You can render partials from within your layout or current actions view with the render or partial methods of the view object.

If you have multiple actions to deal with multiple possible posts from your tabs, then you should set all of these actions to render the same view script, which will then render all of the tabs with data direct from the model.

Bittarman