2008年11月30日星期日

Re: [fw-mvc] Layout Requests

Sorry if anyone is offended about digging this up from the grave.

I have a concern about making actions for this type of functionality.
Correct me if I am wrong but to me the idea of an action is used for
generating the request response not returning some sort of response to other
controller action.

On top of the logical problems you end up with an action that is accessible
through your url parameters.

In the most generalized case such as a navigation would using a standalone
navigation helper be the best practice?


Thank you!

Matthew Weier O'Phinney-3 wrote:
>
> -- Anders Fredriksson <anders@tablefinder.com> wrote
> (on Saturday, 08 March 2008, 04:22 PM +0100):
>> On Mar 8, 2008, at 12:08 PM, Nick Lo wrote:
>>
>> >
>> > On 08/03/2008, at 9:08 PM, Anders Fredriksson wrote:
>> >
>> > > What I want to have done is the following:
>> > >
>> > > I have a default layout which has sections (placeholders) header,
>> > > content, and footer. Fairly common I would say. :)
>> > >
>> > > in my header templates I might want to do different stuff depending
>> on
>> > > what controller I'm in or what action is made.
>> > >
>> > > With the old Layout_Request it was very easy to make a call to a
>> specific
>> > > action in a controller and to render it to the appropriate
>> placeholder.
>> >
>> > ...
>> >
>> > > This solution works, but is in my opinion very ugly. So I'm all for
>> > > suggestions on how to do this in a nice way from controllers, ie not
>> from
>> > > the viewscripts.
>> >
>> > I'm not completely clear what you're looking for as I didn't use Layout
>> > Requests but from your comments above I wonder if you've tried direct
>> > action calls:
>> >
>> > <?php echo $this->action('right-navigation', 'layout', null,
>> > array('right-nav' => $this->rightNav)); ?>
>> >
>> > I was using this one to do pretty well what you describe above though
>> for
>> > a right hand navigation. That call is in the layout script but the
>> logic
>> > is in a LayoutController::rightNavigationAction()
>> >
>> > I cannot remember where this is documented otherwise I'd point to it
>> for
>> > more info.
>> >
>> > Nick
>> >
>> >
>>
>>
>> I'm not sure how I can make this more clear. The solution you suggest
>> would
>> not do it because that line would have to be in the default layout
>> template, which will always be the same for all actions,
>
> You *can* change the layout on the fly from within a view script or a
> controller action:
>
> // within controller action:
> $this->_helper->layout()->setLayout(...);
>
> // within a view script:
> $this->layout()->setLayout(...);
>
> If you have several distinct layouts for your site, this is a really
> good technique.
>
>> and I want to be able to make calls to render certain actions into
>> certain placeholders on the fly. And if I make such a call from a
>> controller it would automatically redirect to that controller.
>
> You don't understand how the action() helper works, methinks. It doesn't
> redirect to that controller, it simply takes the rendered content of
> that action and returns it:
>
> $content = $view->action('right-navigation', 'layout', null,
> array('right-nav' = $rightNav));
>
> This can be called from a view script, or within your controller, etc.
> Now, if you want to capture it into a placeholder, that's pretty simple
> as well:
>
> // in a controller action:
>
> $this->view->placeholder('right-navigation')->append($this->view->action(...));
>
> // within a view script:
> $this->placeholder('right-navigation')->append($this->action(...));
>
> You can use placeholders within your layout view scripts as well -- you
> don't have to rely on the layout segments. They act basically like view
> variables -- if they have nothing in them, nothing is echoed:
>
> // within layout script:
> echo $this->placeholder('right-navigation');
>
> Looking at what you've done below, I can't help but think you're
> over-complicating it, but I don't have the time to try and write up an
> alternative solution for you. Look at my above examples and see if you
> can find an alternative that may be simpler using them.
>
>> but to give a more concrete example (be prepared for the longest mail
>> I've
>> written below) :)
>>
>> my setup:
>>
>> applications/
>> default/
>> controllers/
>> IndexController.php
>> OtherController.php
>> models/
>> Example.php
>> views/
>> layouts/
>> default.tpl
>> scripts/
>> getheader.tpl
>> index/
>> index.tpl
>> sidebar.tpl
>> other/
>> index.tpl
>> foo.tpl
>> sidebar.tpl
>> lib/
>> EZ/
>> Controller/
>> Action.php
>> Layout/
>> Request.php
>> View/
>> Smarty.php
>> public_html/
>> index.php
>>
>>
>> Action.php
>>
>> class EZ_Controller_Action extends Zend_Controller_Action {
>> ...
>> public function init() {
>> ...
>> //Check if this is a layoutRequest. if it is change the response
>> segment
>> so that the result vill render
>> //into a variable named the value of the param EZ_Layout_Request
>> //This is a bit of an ugly solution but necessary since the
>> requestobject's type get lost
>> if ($this->getRequest()->has ( "EZ_Layout_Request" )) {
>> $this->isLayoutRequest = true;
>> $this->_helper->viewRenderer->setResponseSegment (
>> $this->requestObj->getParam ( "EZ_Layout_Request" ) );
>> }
>>
>> //Set default layout template
>> $this->_helper->layout ()->setLayout ('default');
>> }
>>
>> public function preDispatch() {
>> ...
>> if (! ($this->isLayoutRequest === true)) {
>> $layoutRequestHeader = new EZ_Layout_Request ( 'header', 'getheader'
>> );
>> $this->_helper->getHelper ( 'ActionStack' )->pushStack (
>> $layoutRequestHeader );
>> }
>> ...
>> }
>>
>> public function getheaderAction() {
>> if ($this->isLayoutRequest) {
>> $this->view->headline = $this->getHeadline ();
>> $this->view->HeadTitle ( "Example.com - " . $this->view->headline );
>> ...
>> $this->_helper->getStaticHelper ( 'viewRenderer' )->setNoController (
>> true );
>> $this->view->render ( 'getheader.tpl' );
>> } else {
>> $this->_redirect ( "/" );
>> }
>> }
>>
>> ... //other helperfunctions
>> }
>>
>> --------------------->IndexController.php
>>
>> class IndexController extends EZ_Controller_Action {
>> ...
>> public function indexAction() {
>> //do some specific stuff
>> $sidebarLayoutRequest = new EZ_Layout_Request('sidebar','sidebar');
>>
>> $this->_helper->getStaticHelper('ActionStack')->pushStack($sidebarLayoutRequest);
>> $this->view->foo = bar;
>> }
>>
>> public function sidebarAction() {
>> $this->view->someVar = new Example();
>> }
>> ...
>> }
>>
>> -------------------------->OtherController.php
>>
>> class OtherController extends EZ_Controller_Action {
>> public function indexAction() {
>> //do some other stuff
>> $sidebarLayoutRequest = new EZ_Layout_Request('sidebar','sidebar');
>>
>> $this->_helper->getStaticHelper('ActionStack')->pushStack($sidebarLayoutRequest);
>> $this->view->bar = 'foo';
>> }
>>
>> public function fooAction() {
>> //do some specific stuff
>> $sidebarLayoutRequest = new
>> EZ_Layout_Request('sidebar','sidebar','Index'); //have the index sidebar
>> instead
>>
>> $this->_helper->getStaticHelper('ActionStack')->pushStack($sidebarLayoutRequest);
>> }
>>
>> public function sidebarAction() {
>> $this->view->someOtherVar = new Example();
>> }
>>
>> }
>>
>> -------------------------------->default.tpl
>>
>> {$this->doctype()}
>> <html xmlns='http://www.w3.org/1999/xhtml' xml:lang="en" lang="en">
>> <head>
>> {$this->headTitle}
>> {$this->headScript()}
>> {$this->headLink()}
>> {$this->headStyle()}
>> {$this->headMeta()}
>> </head>
>> <body>
>> <div id="doc">
>> <div id="hd" class="header"> {layout section="header"}</div>
>> <div id="bd">
>> <div id="yui-main" class="png">
>> <div id="content" class="yui-g">
>> <!-- YOUR DATA GOES HERE -->
>> {layout section="content"}
>> </div>
>> <div class="yui-u">
>> {layout section="sidebar"}
>> </div>
>> </div>
>> </div>
>> <div id="ft"> {layout section="footer"}</div>
>> </div>
>> </body>
>> </html>
>>
>> ------------------------>index.tpl
>>
>> <p> I really would like some {$foo} now</p>
>>
>> ------------------------>index/sidebar.tpl
>> <h2> IndexSidebarTitle</h2>
>> <p> {$someVar}</p>
>>
>> ------------------------>other/sidebar.tpl
>> <h2> OtherSidebarTitle</h2>
>> <p> {$someOtherVar}</p>
>>
>> -------------------------->Request.php
>> class EZ_Layout_Request extends Zend_Controller_Request_Http {
>> /**
>> * $_nameKey
>> *
>> * @var string
>> */
>> protected $_nameKey = "EZ_Layout_Request";
>>
>> /**
>> * __construct()
>> *
>> * @param string $name
>> * @param string $action
>> * @param string $controller
>> * @param string $module
>> * @param array $params
>> */
>> public function __construct($name=null,$action=null,
>> $controller=null,
>> $module=null,$uri = null) {
>> if($name !== null) $this->setName($name);
>> if($action !== null) $this->setActionName($action);
>> if($controller !== null) $this->setControllerName($controller);
>> if($module !== null) $this->setModuleName($module);
>> parent::__construct($uri);
>> }
>>
>> /**
>> * setName() - This is the layout variable name that will be used
>> when
>> rendering
>> *
>> * @param string $name
>> * @return Zend_Layout_Request
>> */
>> public function setName($name)
>> {
>> $this->setParam($this->_nameKey,$name);
>> return $this;
>> }
>>
>> /**
>> * getName()
>> *
>> * @return string
>> */
>> public function getName()
>> {
>> return $this->getParam($this->_nameKey);
>> }
>>
>> /**
>> * setNameKey()
>> *
>> * @param String $key
>> */
>> public function setNameKey($key = "EZ_Layout_Request") {
>> $this->_nameKey = $key;
>> }
>> }
>> ------------------------------------------------------------------
>>
>> If I have any readers still with me down here, I want to say that this
>> setup is by far optimal, as I always have to check so that stuff that is
>> layoutrequests doesn't add scripts and other stuff more than once.
>>
>> What I want to achieve is to have the exact same functionality that Ralph
>> had in his Xend_Layout, which was the original for the Zend_Layout, but I
>> don't know how to do that just yet.
>>
>> I'm just really surprised that no one else is missing this functionality
>> as
>> it would be very good to have. it would basically mean that all of your
>> actions in all controllers could be treated as separately renderable
>> modules, that you could build up a page from very dynamically.
>>
>> Thanks to anyone who will answer this long post. :)
>>
>> Best,
>>
>> //Anders Fredriksson
>>
>>
>
> --
> Matthew Weier O'Phinney
> PHP Developer | matthew@zend.com
> Zend - The PHP Company | http://www.zend.com/
>
>

--
View this message in context: http://www.nabble.com/Layout-Requests-tp15913170p20766775.html
Sent from the Zend MVC mailing list archive at Nabble.com.

没有评论: