-- 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/