-- Kevin McArthur <[EMAIL PROTECTED]> wrote (on Tuesday, 27 March 2007, 10:22 AM -0700): > Isn't that crossing the view/controller relationship boundary a bit. Would > it not be more correct to subclass Zend_View to provide $this->module and > $this->controller if you were going to take that approach? > > If you're going to create an engine view, maybe create an engine model to > interact with it the way you want to. I'd just be nervous about putting in > controller logic in templates and view html in controllers as it might make > for some fun debugging later. > > If you were to subclass, you could create two arrays $this->stylesheets and > $this->scripts and iterate them in the engine. If there were 0 entries, > then no output would result (and no empty files would be needed). Similarly > you can set the current title, page breadcrumbs etc. > > You could also subclass Zend_Controller_Action instead and provide an > init() method to setup a view object the way you want it, then store it as > $this->view or such. > > Theres lots of options
I've provided three now, one of which had no reliance on the controllers (have the component view set variables to be used by the sitewide view). This built on the original method I suggested of using array variables in the view script -- just setting them from individual views instead of the controller. There are many ways to do this, some involving injections from the controller (and remember, such interactions are part of the MVC pattern, as are interactions between the view and model -- the controller may provide hints to the view as to what should or should not be displayed; the view may pull data directly from the model to display, etc), some using the values already in the view (or the location of the view itself) to determine what data to pull, etc. You say "theres lots of options" -- post them to the list so we can see how *you* tackle the issue. The more concrete solutions, the better! > ----- Original Message ----- > From: "Matthew Weier O'Phinney" <[EMAIL PROTECTED]> > To: <[email protected]> > Sent: Tuesday, March 27, 2007 8:42 AM > Subject: Re: [fw-general] Controller and View Question > > > >-- Greg Neustaetter <[EMAIL PROTECTED]> wrote > >(on Tuesday, 27 March 2007, 08:14 AM -0700): > >>The problem I see with an approach like this is that the view is tied > >>very > >>closely with the controller. Should the controller have any idea about > >>which > >>javascript files need to be included on a particular page? Finding a > >>solution > >>that minimizes the amount of common code that has to be placed in the > >>view but > >>still provides the view with the ability to inject javascript, css, page > >>titles, meta tags, etc to header seems to be a problem I haven't seen > >>answered > >>well in any framework. The template may include a couple javascript or > >>css > >>files by default in every page, but even then, the page may choose to > >>remove > >>the default files if it chooses. > >> > >>Thoughts? > > > >A few. > > > >One is to do something similar to how Zend_Controller_Action::render() > >works, only with your css/js. So, in your sitewide template view script, > >have some logic like this: > > > > <?php > > $request = Zend_Controller_Front::getInstance()->getRequest(); > > $module = $request->getModuleName(); > > $controller = $request->getControllerName(); > > ?> > > <html> > > <head> > > <title><?= $this->escape($this->title) ?></title> > > <link rel="stylesheet" type="text/css" href="/styles/site.css" /> > > <link rel="stylesheet" type="text/css" href="/styles/<?= $module > >?>/<?= $controller ?>.css" /> > > > >In this example, sitewide styles are kept under the /styles/ root in the > >webroot, and then segregated by module and controller: > > > > /styles/ > > news/ > > list.css > > item.css > > blog/ > > archive.css > > > >In this way, you'd have some automation in how CSS (and you can extend > >the idea to JS scripts, too) is injected into the page. The problem is > >that you'd have to ensure that these files existed for each module and > >controller -- which could lead to a ton of empty, unused files on your > >machine. > > > >Another approach is to use set view variables from within component > >views. For example, if I have a view script for the NewsController, I > >could do this: > > > > <?php > > $this->dynamic_header[] = '<link rel="stylesheet" type="text/css" > >href="/styles/news.css" />'; > > ?> > > > >Then, assuming the sitewide template uses the same view object, it now > >has an additional header. This satisfies the requirement you had of > >keeping this logic out of the controller and in the view. It's a bit > >unwieldy, but it also solves the issue presented above of not needing to > >create a CSS file for every controller. > > > >I'm sure others have ideas as well. > > > >>On 3/27/07, Matthew Weier O'Phinney <[EMAIL PROTECTED]> wrote: > >> > >> -- Dale McNeill <[EMAIL PROTECTED]> wrote > >> (on Tuesday, 27 March 2007, 09:19 AM -0500): > >> > I've got some CSS and javascript that I would like to dynamically > >>add to > >> > the HTML header depending on the controller/action. I would like > >>to be > >> > able to append information like appending to the response body. > >>Then > >> > use this information in a site wide template. The only solution > >>that > >> > comes to mind is using a view variable and having each > >>controller/action > >> > get the variable, append it, and write it back to the view. Is > >>there > >> > some functionality that I might be overlooking? - Thanks > >> > > >> > Site wide template: > >> > <html> > >> > <head> > >> > <title> <?php echo $this->title; ?> </title> > >> > <?php echo $this->dynamic_header; ?> > >> > >> Define $dynamic_header as an array in the view object. When you first > >> initialize the view object, do something like this: > >> > >> $view = new Zend_View(); > >> $view->dynamic_header = array(); > >> > >> Then, whenever you want to add to it, just add a new element to the > >> array: > >> > >> $view->dynamic_header[] = '<meta name="keywords" value="zend > >>framework > >> zend_view" /> '; > >> > >> Then, in the view script, iterate over the array: > >> > >> <?php foreach ($this->dynamic_header as $header): > >> echo $header, "\n"; > >> endforeach; ?> > >> > >> Finally, use a Two Step View as I've outlined previously in this > >>thread > >> -- use a dispatchLoopShutdown() plugin to throw the response body > >>into a > >> sitewide template (which it looks like you're doing here). > >> > >> > </head> > >> > <body> > >> > ...common header... > >> > <?php echo $this->content; ?> > >> > ...common footer... > >> > </body> > >> > </html> > >> > > >> > Matthew Weier O'Phinney wrote: > >> > > -- Arnaud Limbourg <[EMAIL PROTECTED]> wrote > >> > > (on Monday, 26 March 2007, 07:04 AM +0200): > >> > > > >> > > > Matthew Weier O'Phinney wrote: > >> > > > > >> > > > > I throw a Zend_View object in the registry, and then access > >>this > >> from my > >> > > > > controllers and plugins. The benefit of doing this is that > >>the > >> > > > > controllers can set values in the view that are unused in > >>their > >> > > > > individual view, but used later in the sitewide template. > >> > > > > > >> > > > > Then, I use a dispatchLoopShutdown() plugin to inject any > >>generated > >> > > > > content into a sitwide template: > >> > > > > > >> > > > > > >> > > > > class SiteTemplatePlugin extends > >>Zend_Controller_Plugin_Abstract > >> > > > > { > >> > > > > public function dispatchLoopShutdown() > >> > > > > { > >> > > > > $response = > >> > > > > > >>Zend_Controller_Front:;getInstance()->getResponse(); > >> > > > > $view = Zend_Registry::get('view'); > >> > > > > $view->content = $response->getBody(); > >> > > > > $response->setBody($view->render(' site.phtml')); > >> > > > > } > >> > > > > } > >> > > > > > >> > > > Which poses a problem when you want to send back json (or > >>whatever) > >> and > >> > > > you don't want a site wide template :) > >> > > > > >> > > > >> > > This was a simple example. But it's actually really easy to > >>return > >> JSON: > >> > > > >> > > public function dispatchLoopShutdown() > >> > > { > >> > > // assume that we've already determined the request is > >>ajax > >> > > $request = $this->getRequest(); > >> > > $response = $this->getResponse(); > >> > > $view = Zend_Registry::get('view'); > >> > > > >> > > if ($request->getParam('isAjax', false)) { > >> > > // Ajax request detected > >> > > // Get any variables set in the view > >> > > $vars = get_object_vars($view); > >> > > > >> > > // Merge with named path segments in response > >> > > $vars = array_merge($vars, $response->getBody(true)); > >> > > > >> > > // Create a header and set the response body to a JSON > >>value > >> > > $resposne->setHeader('Content-Type', 'text/x-json'); > >> > > $response->setBody(Zend_Json::encode($vars)); > >> > > return; > >> > > } > >> > > > >> > > // Otherwise, process as normal > >> > > $view->content = $response->getBody(); > >> > > $response->setBody($view->render('site.phtml')); > >> > > } > >> -- > >> Matthew Weier O'Phinney > >> PHP Developer | [EMAIL PROTECTED] > >> Zend - The PHP Company | http://www.zend.com/ > >> > >> > > > >-- > >Matthew Weier O'Phinney > >PHP Developer | [EMAIL PROTECTED] > >Zend - The PHP Company | http://www.zend.com/ > -- Matthew Weier O'Phinney PHP Developer | [EMAIL PROTECTED] Zend - The PHP Company | http://www.zend.com/
