\documentclass{article}
\usepackage{ulem}
\usepackage{graphicx}
\usepackage{hyperref}
\pagestyle{headings}
\begin{document}
\part{Horde\_View}
PHP 5 library targetted for Horde 4 that implements a view pattern.

\section{Bugs}
\section{People}
<a href="https://wiki.horde.org/ChuckHagenbuch">ChuckHagenbuch</a> is the primary author of Horde\_View.

\section{Description}
\subsection{Notes on views and templates}
Some of this may be badly outdated.

<a href="http://blog.sig9.net/2008/01/21/template-engines/">http://blog.sig9.net/2008/01/21/template-engines/</a>

I use the Two Step View pattern. My applications render content to the<br />
response object (just the application content, none of the site<br />
skeleton), and then in a dispatchLoopShutdown() plugin I pull the<br />
response content and inject it into a sitewide template, and finally<br />
inject that rendered content back into the response object. I've<br />
provided a sample of such a plugin in the past on either the fw-mvc or<br />
fw-general list.

<a href="http://paul-m-jones.com/blog/?p=247">http://paul-m-jones.com/blog/?p=247</a><br />
<a href="http://framework.zend.com/wiki/display/ZFMLGEN/mail/27145">http://framework.zend.com/wiki/display/ZFMLGEN/mail/27145</a><br />
<a href="http://www.ingredients.com.au/nick/2006/06/10/getting-to-know-zend\_view/">http://www.ingredients.com.au/nick/2006/06/10/getting-to-know-zend\textbackslash\{\}\_view/</a><br />
<a href="http://fosterburgess.com/kimsal/?p=237">http://fosterburgess.com/kimsal/?p=237</a>

Horde\_View notes:

\begin{itemize}
\item <a href="http://benramsey.com/archives/zend-framework-view-notes/">http://benramsey.com/archives/zend-framework-view-notes/</a>


\item some way to automatically call views


\item should I change from "script" to "template"?


\end{itemize}
To read:<br />
<a href="https://wiki.horde.org/ZF">rev 4332</a>:

\begin{itemize}
\item Add optional ability to generate notices for undeclared variables in<br />
templates. Use \$view->strictVars(true); to turn on functionality


\item Added Zend\_View\_Helper\_DeclareVars helper. Allows developer to optionally<br />
declare template variables and default values. When used with<br />
strictVars(), will prevent notices by declaring unused variables in the<br />
view object


\end{itemize}
<a href="https://wiki.horde.org/ZF">rev 4338</a>: Added getScriptPath(\$name), getHelperPath(\$name),<br />
getFilterPath(\$name), getHelper(\$name), getFilter(\$name), and getFilters()<br />
methods. Notes:

\begin{itemize}
\item getHelper() and getFilter() will instantiate the filter of \$name if not<br />
already instantiated


\item getHelpers() and getFilters() only return already instantiated helpers and<br />
filters; i.e., they won't return all helpers and filters available


\item getHelperPath() and getFilterPath() will instantiate the associated helper<br />
or filter in the process of discovering the path, if not already<br />
instantiated


\end{itemize}
View notes:

We're using some different "views" to get a useful layout for each purpose.

We start using:

\begin{itemize}
\item portal-layout.php


\item clean-layout.php


\end{itemize}
The first one has the header, footer, top menu, the main content and optionally the left and right menus. The clean layout only has the header and footer.

So, in our scripts we can do the following (extending the Zend\_View component):

\$view = new <a href="https://wiki.horde.org/TemplateView">TemplateView</a>();<br />
\$view->tplMain  = 'articles/view.php';<br />
\$view->tplLeft  = 'articles/leftMenu.php';<br />
\$view->tplRight = 'articles/contextual.php';<br />
\$view->articles = \$oArticles->get();<br />
\$view->render('portal-layout.php');

The "portal-layout.php" is constructed this way:

\$this->render('header.php');<br />
\$this->render('topMenu.php');<br />
if(isset(\$this->tplLeft))<br />
\$this->render(\$this->tplLeft);<br />
\$this->render(\$this->tplMain);<br />
if(isset(\$this->tplRight))<br />
\$this->render(\$this->tplRight);<br />
\$this->render('footer.php');

ACLs and views

I'm not quite sure how I should use ACL with Views. I have a menu where I'd like items not to be visible if users role(s) have no access to it. So I was planning on doing array of the menu items and passing that to the view or passing the whole ACL object to view.

Definitely go for the array of menu items. A simple rule to follow is give the view simple data structures only. Otherwise, should your application code switch from Zend\_Acl to something else, you would need to change every view involved.

One simple approach that i user is to set up a dir like:<br />
/app/views/public/modules/

I have  view helper <a href="https://wiki.horde.org/RenderModule">RenderModule</a>:

<pre><code>
        /**
         * renders a module:
         * moduleDir\_moduleName
         *
         * @param string, module
         */
        public function RenderModule(\$module)\{
            \$view = Zend\_Registry::get('view');
            \$config = Zend\_Registry::get('config');
            \$path = \$config->view->publicModules;
            \$currModule = str\_replace('\_','/',\$module);
            return \$view->render('./' . \$path . '/' . \$currModule . '.tpl.php');
        \}
</code></pre>
so for the show new news module:<br />
dir: /app/views/public/modules/news/newNews.tpl.php

to render it (in the view):<br />
echo \$this-><a href="https://wiki.horde.org/RenderModule">RenderModule</a>('news\_newNews');

Hi Padraic,

I'm currently playing with a portal-like behaviour. I implemented a number of Controller/View pairs as portlets that can be layouted in any way you want on a webpage.

I was initially not planning to mention this so early but to announce it later in this list when it is more mature, but anyway, this little add-on might be of help for you. There's a little demo on

<a href="http://www.rehno.de">http://www.rehno.de</a>

which shows a simple and ugly wireframe layout (simple table layout) that are completely code-driven, i.e. you can adjust them dynamically during runtime. There are three demos on this page: a form example which shows how forms can be implemented as portlets and submitted/ evaluated independently of each other. The second example is a link example which shows how intra-portlet navigation can be implemented. The third example is a modification example which shows how one portlet might change the content of another area of the layout.

Please enable the Inplace debug output to get a better feeling about layouting and portlets within the layout cells.

If you like the demos and like to contribute or give feedback, feel free to contact me!

Regards,

Stephan

<a href="http://blog.astrumfutura.com/archives/282-Complex-Views-with-the-Zend-Framework-Part-2-View-Helper-Pattern.html">http://blog.astrumfutura.com/archives/282-Complex-Views-with-the-Zend-Framework-Part-2-View-Helper-Pattern.html</a>

I currently use a programmatic description for the layout, it is stored into so-called containers which are built of frames which in turn might contain further (sub) containers or portlets.

It basically looks like this:

\$container = new <a href="https://wiki.horde.org/ContainerModel">ContainerModel</a>(<a href="https://wiki.horde.org/ContainerModel">ContainerModel</a>::VERTICAL);<br />
\$container->addFrame("topmenu", "<a href="https://wiki.horde.org/TopMenu">TopMenu</a>", <a href="https://wiki.horde.org/ContainerModel">ContainerModel</a>::MAXSIZE);

\$subcontainer = new <a href="https://wiki.horde.org/ContainerModel">ContainerModel</a>(<a href="https://wiki.horde.org/ContainerModel">ContainerModel</a>::HORIZONTAL, \$container);<br />
\$subcontainer->addFrame("mainspace", null, <a href="https://wiki.horde.org/ContainerModel">ContainerModel</a>::MAXSIZE);<br />
\$container->addChild("contentspace", \$subcontainer, <a href="https://wiki.horde.org/ContainerModel">ContainerModel</a>::MAXSIZE);

As mentioned before, containers might be presented horizontally or vertically. The addFrame() command is passed the frame identifier, the portlet controller name (might be null) and the sizing.

The rendering is done using the container controller:

\$controller = new <a href="https://wiki.horde.org/ContainerController">ContainerController</a>(\$container);<br />
\$controller->setRequestResponse(\$this->\_request, \$this->\_response);

which is passed to the view. In the view.tpl.php file,

echo \$this->containerController->render();

is called. Using the php DOM parser, I'm replacing all hyperlinks in the portlets' html output. That's about it :)

The implementation however is far from being complete. For example there is only a limited number of error checks implemented currently, also frame size is only supported in a limited why as I'm using tables for layouting. div sections are probably better.

Date: Thu, 19 Apr 2007 12:48:33 -0500<br />
From: Dale <a href="https://wiki.horde.org/McNeill">McNeill</a> <<a href="https://wiki.horde.org/mailto:dale.mcneill@alchemysystems.com">dale.mcneill@alchemysystems.com</a>>

I use a dispatchLoopShutdown plugin.  This plugin is able to deal with both AJAX responses as well as a normal HTML response. Here's the code:

class <a href="https://wiki.horde.org/SiteTemplatePlugin">SiteTemplatePlugin</a> extends Zend\_Controller\_Plugin\_Abstract \{

<pre><code>public function dispatchLoopShutdown\textbackslash\{\}(\textbackslash\{\})
\textbackslash\{\}\{
    * assume that we've already determined the request is ajax
    \$request  = \$this-\textbackslash\{\}>getRequest\textbackslash\{\}(\textbackslash\{\});
    \$response = \$this-\textbackslash\{\}>getResponse\textbackslash\{\}(\textbackslash\{\});
    \$view     = Zend\textbackslash\{\}\_Registry::get\textbackslash\{\}('view'\textbackslash\{\});

    if \textbackslash\{\}(\$request-\textbackslash\{\}>getParam\textbackslash\{\}('isAjax'\textbackslash\{\})\textbackslash\{\}) \textbackslash\{\}\{
        * Ajax request detected
        * Get any variables set in the view
        \$vars = get\textbackslash\{\}\_object\textbackslash\{\}\_vars\textbackslash\{\}(\$view\textbackslash\{\});

        * Merge with named path segments in response
        \$vars = array\textbackslash\{\}\_merge\textbackslash\{\}(\$vars, \$response-\textbackslash\{\}>getBody\textbackslash\{\}(true\textbackslash\{\})\textbackslash\{\});

        * Create a header and set the response body to a JSON value
        \$response-\textbackslash\{\}>setHeader\textbackslash\{\}('Content-Type', 'text/x-json'\textbackslash\{\});
        \$response-\textbackslash\{\}>setBody\textbackslash\{\}(Zend\textbackslash\{\}\_Json::encode\textbackslash\{\}(\$vars\textbackslash\{\})\textbackslash\{\});
        return;
    \textbackslash\{\}\}

    * Otherwise, process as normal
    \$view-\textbackslash\{\}>assign\textbackslash\{\}(\$response-\textbackslash\{\}>getBody\textbackslash\{\}(true\textbackslash\{\})\textbackslash\{\});
    \$response-\textbackslash\{\}>setHeader\textbackslash\{\}('Content-Type', 'text/html'\textbackslash\{\});
    \$response-\textbackslash\{\}>setBody\textbackslash\{\}(\$view-\textbackslash\{\}>render\textbackslash\{\}('site.php'\textbackslash\{\})\textbackslash\{\});
\textbackslash\{\}\}
</code></pre>
\}

The site wide template that I use is composed of a header, 3 columns, and a footer.  The header and footer are the same for each page.  I assign the content for each column by appending the response object with a named section.  The named sections eventually become the view variables used in the site template.  Here's an example of a normal HTML response:

class <a href="https://wiki.horde.org/IndexController">IndexController</a> extends Zend\_Controller\_Action \{

<pre><code>* Normal HTML response
public function indexAction\textbackslash\{\}(\textbackslash\{\})
\textbackslash\{\}\{
    \$response    = \$this-\textbackslash\{\}>getResponse\textbackslash\{\}(\textbackslash\{\});
    \$view        = Zend\textbackslash\{\}\_Registry::get\textbackslash\{\}('view'\textbackslash\{\});
    \$view-\textbackslash\{\}>title = 'My Index Title';
    \$response-\textbackslash\{\}>appendBody\textbackslash\{\}(\$view-\textbackslash\{\}>render\textbackslash\{\}('index\textbackslash\{\}\_css.php'\textbackslash\{\}), 'inline\textbackslash\{\}\_css'\textbackslash\{\});
    \$response-\textbackslash\{\}>appendBody\textbackslash\{\}(\$view-\textbackslash\{\}>render\textbackslash\{\}('index\textbackslash\{\}\_left.php'\textbackslash\{\}), 'left\textbackslash\{\}\_content'\textbackslash\{\});
    \$response-\textbackslash\{\}>appendBody\textbackslash\{\}(\$view-\textbackslash\{\}>render\textbackslash\{\}('index\textbackslash\{\}\_center.php'\textbackslash\{\}), 'center\textbackslash\{\}\_content'\textbackslash\{\});
    \$response-\textbackslash\{\}>appendBody\textbackslash\{\}(\$view-\textbackslash\{\}>render\textbackslash\{\}('index\textbackslash\{\}\_right.php'\textbackslash\{\}), 'right\textbackslash\{\}\_content'\textbackslash\{\});
\textbackslash\{\}\}

* AJAX response
public function viewAction\textbackslash\{\}(\textbackslash\{\})
\textbackslash\{\}\{
    \$request = \$this-\textbackslash\{\}>getRequest\textbackslash\{\}(\textbackslash\{\});
    \$request-\textbackslash\{\}>setParam\textbackslash\{\}("isAjax", true\textbackslash\{\});

    \$view = Zend\textbackslash\{\}\_Registry::get\textbackslash\{\}('view'\textbackslash\{\});
    \$view-\textbackslash\{\}>status  = 0;
    \$view-\textbackslash\{\}>message = "Problem encounted";
</code></pre>
\}

\}

Here's the site wide template:

<!DOCTYPE html PUBLIC "-*<a href="https://wiki.horde.org/W3C">W3C</a>\textit{DTD XHTML 1.0 Strict}EN" "http:*<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;\&gt;">www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"\textbackslash\{\}></a><br />
<html xmlns="<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>" xml:lang="en" lang="en"><br />
<head><br />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><br />
<title><?php echo \$this->escape(\$this->title); ?></title><br />
<script src="/javascript/json.js"></script><br />
<style type="text/css"><br />
<?php echo \$this->inline\_css; ?><br />
</style><br />
</head>

<body>

<pre><code>\textbackslash\{\}<div id="header"\textbackslash\{\}>
   \textbackslash\{\}<div id="header"\textbackslash\{\}>This is the header.\textbackslash\{\}</div\textbackslash\{\}>
\textbackslash\{\}</div\textbackslash\{\}>

\textbackslash\{\}<div id="container"\textbackslash\{\}>

    \textbackslash\{\}<div id="center" class="column"\textbackslash\{\}>
        \textbackslash\{\}<?php echo \$this-\textbackslash\{\}>center\textbackslash\{\}\_content; ?\textbackslash\{\}>
    \textbackslash\{\}</div\textbackslash\{\}>

    \textbackslash\{\}<div id="left" class="column"\textbackslash\{\}>
        \textbackslash\{\}<?php echo \$this-\textbackslash\{\}>left\textbackslash\{\}\_content; ?\textbackslash\{\}>
    \textbackslash\{\}</div\textbackslash\{\}>

    \textbackslash\{\}<div id="right" class="column"\textbackslash\{\}>
        \textbackslash\{\}<?php echo \$this-\textbackslash\{\}>right\textbackslash\{\}\_content; ?\textbackslash\{\}>
    \textbackslash\{\}</div\textbackslash\{\}>

\textbackslash\{\}</div\textbackslash\{\}>

\textbackslash\{\}<div id="footer-wrapper"\textbackslash\{\}>
    \textbackslash\{\}<div id="footer"\textbackslash\{\}>This is the footer.\textbackslash\{\}</div\textbackslash\{\}>
\textbackslash\{\}</div\textbackslash\{\}>
</code></pre>
</body><br />
</html>

Date: Thu, 19 Apr 2007 13:30:27 -0400<br />
From: Matthew Weier O'Phinney <<a href="https://wiki.horde.org/mailto:matthew@zend.com">matthew@zend.com</a>><br />
To: <a href="https://wiki.horde.org/mailto:fw-general@lists.zend.com">fw-general@lists.zend.com</a>

To implement Two Step View, I typically use a dispatchLoopShutdown() plugin, something like this:

<pre><code>class Wopnet\textbackslash\{\}\_Plugins\textbackslash\{\}\_SiteTemplate extends Zend\textbackslash\{\}\_Controller\textbackslash\{\}\_Plugin\textbackslash\{\}\_Abstract \textbackslash\{\}\{

    /**
     \textbackslash\{\}* View script path
     \textbackslash\{\}* @var string
     \textbackslash\{\}*/
    public \$directory;

    /**
</code></pre>
\begin{itemize}
\item View script for sitewide template


\item @var string<br />
*/<br />
public \$file;

<pre><code>  /**
   \textbackslash\{\}* View object
   \textbackslash\{\}* @var Zend\textbackslash\{\}\_View\textbackslash\{\}\_Interface
   \textbackslash\{\}*/
  public \$view;

  /**
</code></pre>

\item Constructor<br />
*


\item Get the script path to the sitewide view scripts, as well as the site


\item template name. If not passed in the constructor, grab from the sitewide


\item configuration, suing the key \$config->vars->path->app to determine the


\item script path for site templates, and \$config->templates->site->filename


\item to determine the sitewide view script.


\item 
\item @param  string \$file


\item @param  string \$directory


\item @return void<br />
*/<br />
public function \_\_construct(\$file = null, \$directory = null)<br />
\{<br />
if (Zend\_Registry::isRegistered('view')) \{<br />
\$this->view = Zend\_Registry::get('view');<br />
\} else \{<br />
\$this->view = new Zend\_View();<br />
\}

<pre><code>      \$config = Zend\textbackslash\{\}\_Registry::get\textbackslash\{\}('siteConfig'\textbackslash\{\});
      if \textbackslash\{\}(\textbackslash\{\}(null \textbackslash\{\}!== \$directory\textbackslash\{\}) \textbackslash\{\}\&\textbackslash\{\}\& is\textbackslash\{\}\_dir\textbackslash\{\}(\$directory\textbackslash\{\})\textbackslash\{\}) \textbackslash\{\}\{
          \$this-\textbackslash\{\}>directory = \$directory;
      \textbackslash\{\}\} else \textbackslash\{\}\{
          if \textbackslash\{\}(\textbackslash\{\}!isset\textbackslash\{\}(\$config-\textbackslash\{\}>vars-\textbackslash\{\}>path-\textbackslash\{\}>app\textbackslash\{\})\textbackslash\{\}) \textbackslash\{\}\{
              throw new Exception\textbackslash\{\}('No sitewide app path set'\textbackslash\{\});
          \textbackslash\{\}\}
          \$this-\textbackslash\{\}>directory = \$config-\textbackslash\{\}>vars-\textbackslash\{\}>path-\textbackslash\{\}>app . DIRECTORY\textbackslash\{\}\_SEPARATOR . 'views' . DIRECTORY\textbackslash\{\}\_SEPARATOR . 'scripts';
      \textbackslash\{\}\}

      if \textbackslash\{\}(\textbackslash\{\}!is\textbackslash\{\}\_dir\textbackslash\{\}(\$this-\textbackslash\{\}>directory\textbackslash\{\})\textbackslash\{\}) \textbackslash\{\}\{
          throw new Exception\textbackslash\{\}('Sitewide view script path does not exist'\textbackslash\{\});
      \textbackslash\{\}\}

      if \textbackslash\{\}(null \textbackslash\{\}!== \$file\textbackslash\{\}) \textbackslash\{\}\{
          \$this-\textbackslash\{\}>file = \textbackslash\{\}(string\textbackslash\{\}) \$file;
      \textbackslash\{\}\} else \textbackslash\{\}\{
          if \textbackslash\{\}(\textbackslash\{\}!isset\textbackslash\{\}(\$config-\textbackslash\{\}>templates-\textbackslash\{\}>site-\textbackslash\{\}>filename\textbackslash\{\})\textbackslash\{\}) \textbackslash\{\}\{
              throw new Exception\textbackslash\{\}('Sitewide template not set in config'\textbackslash\{\});
          \textbackslash\{\}\}
          \$this-\textbackslash\{\}>file = \$config-\textbackslash\{\}>templates-\textbackslash\{\}>site-\textbackslash\{\}>filename;
      \textbackslash\{\}\}

      if \textbackslash\{\}(\textbackslash\{\}!file\textbackslash\{\}\_exists\textbackslash\{\}(\$this-\textbackslash\{\}>directory . DIRECTORY\textbackslash\{\}\_SEPARATOR . \$this-\textbackslash\{\}>file\textbackslash\{\})\textbackslash\{\}) \textbackslash\{\}\{
          throw new Exception\textbackslash\{\}("Sitewide view script '\textbackslash\{\}\{\$this-\textbackslash\{\}>directory\textbackslash\{\}\}/\textbackslash\{\}\{\$this-\textbackslash\{\}>file\textbackslash\{\}\}' does not exist"\textbackslash\{\});
      \textbackslash\{\}\}

      \$this-\textbackslash\{\}>view-\textbackslash\{\}>addScriptPath\textbackslash\{\}(\$this-\textbackslash\{\}>directory\textbackslash\{\});
  \textbackslash\{\}\}

  /\textbackslash\{\}*\textbackslash\{\}*
</code></pre>

\item Inject generated content into sitewide view script<br />
*


\item @param Zend\_Controller\_Request\_Abstract \$request


\item @return void<br />
*/<br />
public function dispatchLoopShutdown()<br />
\{<br />
\$front    = Zend\_Controller\_Front::getInstance();<br />
\$response = \$front->getResponse();<br />
\$body     = \$response->getBody();

<pre><code>      \$this-\textbackslash\{\}>view-\textbackslash\{\}>setScriptPath\textbackslash\{\}(\$this-\textbackslash\{\}>directory\textbackslash\{\});
      \$this-\textbackslash\{\}>view-\textbackslash\{\}>assign\textbackslash\{\}(get\textbackslash\{\}\_object\textbackslash\{\}\_vars\textbackslash\{\}(\$response\textbackslash\{\})\textbackslash\{\});
      \$this-\textbackslash\{\}>view-\textbackslash\{\}>content = \$body;
      \$response-\textbackslash\{\}>setBody\textbackslash\{\}(\$this-\textbackslash\{\}>view-\textbackslash\{\}>render\textbackslash\{\}(\$this-\textbackslash\{\}>file\textbackslash\{\})\textbackslash\{\});
  \textbackslash\{\}\}
</code></pre>
\}


\end{itemize}
Now, that's all fine and dandy, but it doesn't get the widgets in like you're discussing. For that, I've seen a few ideas. One is a Zend View Helper somebody posted to JIRA (and I think there's also a similar proposal in the wiki). In those, the helper basically does something like this:

<pre><code>public function widget\textbackslash\{\}(\$action, \$controller, \$module, array \$params = array\textbackslash\{\}(\textbackslash\{\})\textbackslash\{\})
\textbackslash\{\}\{
    \$front   = Zend\textbackslash\{\}\_Controller\textbackslash\{\}\_Front::getInstance\textbackslash\{\}(\textbackslash\{\});
    \$request = clone \$front-\textbackslash\{\}>getRequest\textbackslash\{\}(\textbackslash\{\});
    \$request-\textbackslash\{\}>setActionName\textbackslash\{\}(\$action\textbackslash\{\})
            -\textbackslash\{\}>setControllerName\textbackslash\{\}(\$controller\textbackslash\{\})
            -\textbackslash\{\}>setModuleName\textbackslash\{\}(\$module\textbackslash\{\})
            -\textbackslash\{\}>setParams\textbackslash\{\}(\$params\textbackslash\{\});
    \$response = new Zend\textbackslash\{\}\_Controller\textbackslash\{\}\_Response\textbackslash\{\}\_Http\textbackslash\{\}(\textbackslash\{\});
    \$front-\textbackslash\{\}>getDispatcher\textbackslash\{\}(\textbackslash\{\})-\textbackslash\{\}>dispatch\textbackslash\{\}(\$request, \$response\textbackslash\{\});
    return \$response-\textbackslash\{\}>getBody\textbackslash\{\}(\textbackslash\{\});
\textbackslash\{\}\}
</code></pre>
(this is rough; I haven't tested this at all). Then, you would call this in your views to grab the necessary components of your page:

<pre><code>\textbackslash\{\}<?= \$this-\textbackslash\{\}>widget\textbackslash\{\}('items', 'list', 'blog', array\textbackslash\{\}('limit' =\textbackslash\{\}> 10\textbackslash\{\})\textbackslash\{\}) ?\textbackslash\{\}>
</code></pre>
There's a little overhead, but not much. The con side to this is that your widgets don't get to tie into the dispatch loop, so if you were doing any ACL checks in a preDispatch() plugin, for instance, you'd lose those checks.

Theoretically, you could call \$front->dispatch(\$request, \$response), but this would overwrite the current request/response objects, and could lead to some unintended behaviour.

I wanted to post this now 1 week or so but i am very busy and didn't had time to write a<br />
proper email. I don't have enough now :( but still trying to participate.

I already posted some time - in various forums/list - ago this problems raised by working<br />
on big sites (with complex views). And problems are far more complicated, basically the<br />
entire Controller, Action, View side of ZF is not designed for some "real" sites.

The best structure i used before ZF was this way:

\begin{itemize}
\item One database (could be .xml based better) with page entires


\item Each page is having at View side an index, a layout, and multiple zones.


\end{itemize}
Index is the top structure, each application can have multiple indexes, but most have<br />
just one. Samples: main index, index for a popup window which displays an image, aso.

An index has associated ONE layout which means the same "frame" (index) can on content<br />
side have different structure. Each index has insertion point for layout.

Each layout has associated ONE OR MORE zone files, each zone would display content from a<br />
diff data source. Each layout has insertion points for zones

Online shop sample:

\begin{itemize}
\item for an online shop the left side of the main layout can have a zone where on different<br />
pages are displayed different things. But layout is the same, just zones to be bound are<br />
different. Sample: main page having on that zone list of all new products; a product<br />
details page having into zone list of all related products aso.


\end{itemize}
\begin{itemize}
\item Each zone is having a controller which is responsible for preparing data for that zone


\end{itemize}
Steps for working with model:<br />
a) The bootstrapper is identifying current page then is query-ing database of pages<br />
requesting info about that page (index, layout, zones, title page, aso, basically any<br />
custom info can be added).

b) All zone controllers are called so the all data is ready

c) Proper index is rendered, and on insertion point on index file is rendered layout for<br />
that page. Again, at insertion points for zone on that layout are rendered proper zones<br />
(specific for each page)

So, this model is far more appropriate for big sites and i worked with this model a lot.<br />
I spent lot of time trying to reach something similar on ZF, and had to rewrite lot of<br />
stuffs and is big mess... I simply think the way is made Controller, Action, View side of<br />
ZF is not appropriate for working on some real sites.

Any developer who tries to jump with ZF in this situations is going to have a nightmare.<br />
Personally i don't know why are needed Controllers and Actions in current format, aso.

I don't wanna sound like criticism, is just my experience working on some real -<br />
production - stuff.

I?m not happy with the current View implementation.  First I?ll layout my criticism, then suggest what I think may be an answer.  I realize this won?t make it into the next release or anything like that but, I would like to know what people think about it

Basically, what I want is for the View to be more like the Controller.  I want it beefier, meatier, able to stand on its own as part of the MVC.  The MVC needs more V.  As things stand now, the View has all but disappeared into the Controller?s Action helper.  It needs to be brought out and made a powerful component in its own right.

The viewRenderer should be a plug-in for the View, not the other way around.  The viewRenderer should be to the View, what the router is to the Front Controller.  People could then use a default viewRenderer or slot in a custom viewRenderer, just as they now can change routers.

The View should be able to host plug-ins like the Front Controller does.  The plug-ins could have methods like preRender, postRender to allow for such things as selecting skins for the page (preRender) or running the page through tidy (postRender).

The view should have helpers.  In particular, there are two helper classes worth considering.  View\_Wrappers and View\_Filters.   Wrappers add to, filters take away.

Suppose you have a row from a database and you only want the 1st, 3rd and 5th . You might write:

\$info =  filter(array(?1?,?3?,?5?),  \$row);

A wrapper might follow the decorator pattern and do something like this:

\$list = wrap(?list?,\$array);  // creates an html list out of an array

Wrappers can be chained together.

There are lots of things to be puzzled out, but the above is the gist.

Implementation shouldn?t be too hard.  Much of the design for plug-ins and such can come from the Front Controller.   Instead of extending the view class, a new class named Zend\_Alternative\_View or something could be used.  This way you could use the old View while proto-typing the new Zend\_Alternative\_View.

So, what do you say?  Could it be ready for Zend 2.0?

\section{Resources}

\noindent\rule{\textwidth}{1pt}
Back to the <a href="https://wiki.horde.org/Project">Project List</a>

\end{document}
