Skip to end of metadata
Go to start of metadata

<h1>Zend Layout / View Enhancement Notes</h1>

<p>This is a page for my Zend_Layout research and brainstorming.</p>

<ac:macro ac:name="toc"><ac:parameter ac:name="maxLevel">2</ac:parameter><ac:parameter ac:name="printable">false</ac:parameter><ac:parameter ac:name="type">flat</ac:parameter></ac:macro>

<h2>Zend_View_Enhanced</h2>
<ul>
<li>Url: <ac:link><ri:page ri:content-title="Zend_View Enhanced - Pádraic Brady" ri:space-key="ZFPROP" /><ac:link-body>Zend_View_Enhanced</ac:link-body></ac:link></li>
</ul>

<h3>Layouts</h3>
<p>Don't like this implementation. Basically, it requires adding new functionality to Zend_View, which is already getting bloated, abstracts the implementation too much, and requires complex mechanics in the application views in order to aggregate content.</p>

<p>A better solution would be a view decorator that could aggregate content and assign it to a 'layout' view.</p>

<h3>Partials</h3>
<p>This is solid, and has a verifiable need. Jack Sleight also notes that it would be nice to have a way to pass a collection of data that could be looped over; our idea is a second partial helper, partialLoop(), with an API like:</p>

<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
$this->partialLoop($partial, $data);
]]></ac:plain-text-body></ac:macro>

<h3>Controllers</h3>
<p>Needs some work: </p>
<ul>
<li>Need to ensure ViewRenderer integration continues to work properly – that it uses the appropriate request object to make decisions</li>
<li>What happens if a _forward() or _redirect() is called in the dispatched controller? is this silently ignored?</li>
</ul>

<h3>Placeholders </h3>
<p>Seems clunky. While I understand why it's done as a single class, the notation seems pretty clunky and not intuitive to how view helpers are typically done. However, that said, the actual implementation is solid, and accomplishes the goals.</p>

<p><strong>Update:</strong> Ralph and I discussed this in depth. Basically, placeholders <strong>already exist</strong>, assuming the same view instance is used: view variables. The reason to have a placeholder implementation is for the following tasks:</p>

<ul>
<li>Handling collections (allowing prepending, appending, and inserting into a collection of data, including sorting.</li>
<li>Allowing custom prefixes, postfixes, and separators for collections (for instance, prefixing the collection with "<ul><li>", postfixing with "</li></ul>", and separating with "</li><li>").</li>
<li>Capturing output to variables</li>
<li>Consistent API</li>
</ul>

<p>The underlying datastore is an array of ArrayObjects. </p>

<p>The API would look something like this:</p>

<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
// Set a scalar placeholder:
<? $this->placeholder('foo')->set('xxx') ?>

// Use implicit collection properties to append values to 'foo' placeholder:
<? $this->placeholder('foo')->append('bar') ?>
<? $this->placeholder('foo')->append('baz') ?>
<? $this->placeholder('foo')->append('bat') ?>

// Sort the 'foo' collection:
<? $this->collection('foo')->sort() ?>

// Add prefix/suffix/separator:
<?
$this->placeholder('foo')->setPrefix('<ul><li>');
$this->placeholder('foo')->setPostfix('</li></ul>');
$this->placeholder('foo')->setSeparator('</li><li>');

// Echo the 'foo' collection:
<?= $this->placeholder('foo') ?>

// Result:
// <ul><li>bar</li><li>bat</li><li>baz</li><li>xxx</li></ul>
]]></ac:plain-text-body></ac:macro>

<h4>Capture content helper</h4>
<p>At times, a particular application may want to create placeholder content on-the-fly without needing to forward to other actions or call specialized helpers. The easy way to do so is using output buffering to capture data. The placeholder helper would provide a mechanism for this:</p>

<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
<? $this->placeholder('foo')->captureStart() ?>
<div>
<h4><?= $this->title ?></h4>
<ul>
<? foreach ($this->collection as $item): ?>
<li><?= $item ?></li>
<? endforeach ?>
</ul>
</div>
<? $this->placeholder('foo')->captureEnd() ?>

// Later:
<?= $this->placeholder('foo') ?>
]]></ac:plain-text-body></ac:macro>

<p>captureStart() would allow an optional parameter to hint whether the data collected would overwrite or append the placeholder contents (i.e., if the result will be a scalar or part of a collection).</p>

<h4>How to get values?</h4>
<p>One obvious issue, if we allow either scalar or collection values in<br />
placeholders, is how to get the value. Consider this:</p>

<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
$foo = $this->placeholder('foo');
]]></ac:plain-text-body></ac:macro>

<p>$foo is now an ArrayObject – which might seem odd if you set it to a scalar value. However, to preserve the capabilities of the placeholder, it makes sense to still return as an ArrayObject – which allows for the __toString() implementation, etc. If the value is desired, I suggest adding a toValue() method:</p>

<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
$foo = $this->placeholder('foo')->toValue();
]]></ac:plain-text-body></ac:macro>

<p>If the placeholder consists of a single value, it would return that single value; if it is a collection, it would return the value as returned by ArrayObject::getArrayCopy().</p>

<h3>Additional Helpers</h3>
<p><strong>General comments:</strong> Same as with placeholders: having the view helper return an object instead of directly placing the values seems counter to how most view helpers are created. I suggest that most of these should overload the helper method to allow the following:</p>

<ul>
<li>no arguments: return the value</li>
<li>single empty argument: unset it</li>
<li>single non-empty argument: set the value</li>
</ul>

<p>In the case of those that allow setting multiple values, passing an empty value for an index would unset it, passing just the index would retrieve it, and passing no arguments would return the object.</p>

<h4>Doctype</h4>
<p>This is basically for two purposes: </p>

<ul>
<li>To output the appropriate doctype declaration in a layout script</li>
<li>To hint to other helpers (headScript()) how to format their contents (e.g. XHTML/XML doctypes need <script> to wrap JS in CDATA tags</li>
</ul>

<h4>Additional ones?</h4>
<p>Paddy addresses several:</p>

<ul>
<li><link> generators</li>
<li><script> generators</li>
<li><meta> generators</li>
</ul>

<p>These should extend the placeholder helper.</p>

<h3>Zend_View_Factory</h3>
<p>Not sure I see a clear need for this. However, it could make it possible to eliminate the need to specify the view suffix when calling things like partial() and render() within view scripts, and also allow normalization of paths and file names. The ViewRenderer would proxy to this instead of Zend_View_Abstract if used.</p>

<h2>Zend_Layout</h2>
<ul>
<li>URL: <ac:link><ri:page ri:content-title="Zend_Layout" ri:space-key="ZFPROP" /></ac:link><br />
Relies on the response object for variable storage. This is handy, as you can then use the named response segment to target content to appropriate places. However, it ties Zend_Layout to the response object.</li>
</ul>

<p>Another possible strategy is to use a postDispatch() plugin to pluck data out of the response object and place it in a registry in Zend_Layout, and then to create accessors in Zend_Layout to allow specifying content.</p>

<p>Don't necessarily like the singleton strategy. While it ensures that a single Zend_Layout instance exists, this may be possible by instantiating the plugin first, and having an accessor to retrieve it, or instantiating and passing to the plugin and various other helpers, perhaps via a factory.</p>

<h2>Symfony</h2>
<ul>
<li>URL: <a href="http://www.symfony-project.com/book/trunk/07-Inside-the-View-Layer">http://www.symfony-project.com/book/trunk/07-Inside-the-View-Layer</a></li>
</ul>

<h3>Theory</h3>
<ul>
<li>Views accept optional decorators</li>
<li>Layouts are decorators</li>
<li>Renderer class renders view, and decorates with any decorators</li>
</ul>

<h3>Operation</h3>
<ul>
<li>Layout selection
<ul>
<li>from YAML config</li>
<li>in the action
<ul>
<li>$this->setLayout($name)</li>
<li>setting to false disables layout</li>
<li>AJAX actions have no layout by default</li>
</ul>
</li>
</ul>
</li>
<li>Slots
<ul>
<li>Used by layouts, templates and partials</li>
<li>Basically a placeholder</li>
<li>Retrieval:
<ul>
<li>has_slot($name) - does the slot exist?</li>
<li>include_slot($name) - pull in the content</li>
</ul>
</li>
<li>Creation:
<ul>
<li>slot($name) - start capture</li>
<li>end_slot() - ends capture</li>
<li>example:
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
<?php slot('sidebar') ?>
<h1>User details</h1>
<dl>
<dt>Name:</dt><dd><?= $user->getName() ?></dd>
<dt>Email:</dt><dd><?= $user->getEmail() ?></dd>
</dl>
<?php end_slot() ?>
]]></ac:plain-text-body></ac:macro></li>
</ul>
</li>
</ul>
</li>
<li>Views
<ul>
<li>shortcut variables:
<ul>
<li>$sf_context (sfContext object) (what's this?)</li>
<li>$sf_request (request object)</li>
<li>$sf_params (parameters from request object)</li>
<li>$sf_user (current user session object)</li>
</ul>
</li>
<li>extra methods
<ul>
<li>getRequestParameter()</li>
</ul>
</li>
</ul>
</li>
<li>Layout template
<ul>
<li><head> population from response object:
<ul>
<li>include_http_metas()</li>
<li>include_metas()</li>
<li>include_title()</li>
<li>Response methods:
<ul>
<li>addHttpMeta()</li>
<li>addMeta()</li>
<li>setTitle()</li>
<li>addStyleSheet()</li>
<li>addJavaScript()</li>
</ul>
</li>
<li>JS, CSS files are auto-included in layout via a filter</li>
</ul>
</li>
<li>content population from view:
<ul>
<li>$sf_data->getRaw('sf_content')</li>
</ul>
</li>
</ul>
</li>
</ul>

<h3>Pros</h3>
<p>Moving rendering to separate class means that you can have separate views with their own namespaces. Additionally, it means you can attach any number of decorators to a view, allowing an easy way to render something from the inside out.</p>

<p>The idea of functions or methods for retrieving content to inject in the layout is good; makes layout logic simpler and more configurable.</p>

<p>Also like the idea of auto-injecting various objects/vars into the views – good candidates are the request object and front controller.</p>

<p>Placeholders are a good concept, though I hate the 'slots' terminology.</p>

<h3>Cons</h3>
<ul>
<li>Would likely mean either a complete rewrite of Zend_View to separate rendering details from configuation details, or adding logic to Zend_View_Abstract to allow attaching decorator templates.</li>
</ul>

<ul>
<li>Wouldn't allow for re-use of a single view object for multiple rendered views.</li>
</ul>

<ul>
<li>Don't like the idea that scripts/css are linked in via filtering; too much magic.</li>
</ul>

<ul>
<li>Too much coupling with both view and controller.</li>
</ul>

<h2>Cake</h2>
<ul>
<li>URL: <a href="http://manual.cakephp.org/chapter/views">http://manual.cakephp.org/chapter/views</a></li>
</ul>

<h3>Operation</h3>
<ul>
<li>Handled jointly by Controller and View class
<ul>
<li>Controller provides layout info to View</li>
</ul>
</li>
<li>Controller
<ul>
<li>$layoutPath
<ul>
<li>indicates path to layout files</li>
</ul>
</li>
<li>$pageTitle
<ul>
<li>indicates text to use in <title> of layout script</li>
</ul>
</li>
<li>$layout
<ul>
<li>indicates actual layout script to render; defaults to 'default'</li>
</ul>
</li>
<li>$autoLayout
<ul>
<li>flag; render layouts automatically; default on</li>
</ul>
</li>
<li>render()
<ul>
<li>second argument is layout to use</li>
<li>turns off autoRender</li>
<li>Calls view->render($action, $layout, $file)</li>
</ul>
</li>
</ul>
</li>
<li>View
<ul>
<li>render()
<ul>
<li>If autoLayout and layout both true, calls renderLayout()</li>
</ul>
</li>
<li>renderLayout()
<ul>
<li>takes content and renders a view from the layout file</li>
<li>uses properties for title, scripts</li>
<li>assigns:
<ul>
<li>content_for_layout</li>
<li>title_for_layout</li>
<li>scripts_for_layout</li>
<li>cakeDebug</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>

<h3>Pros</h3>
<ul>
<li>Predictable.</li>
<li>Configurable (can choose layout path, layout script, whether or not to use it).</li>
<li>Could theoretically be used even without MVC (rendering of layouts is done in View::render())</li>
</ul>

<h3>Cons</h3>
<ul>
<li>Cannot configure names of 'special' layout variables.</li>
<li>No solid placeholder implementation.</li>
</ul>

<h2>Solar</h2>
<ul>
<li>URL: <a href="http://solarphp.com/manual/Getting_started/Views_and_layouts">http://solarphp.com/manual/Getting_started/Views_and_layouts</a></li>
</ul>

<h3>Operation</h3>
<ul>
<li>Handled in page controller</li>
<li>Properties define behaviour
<ul>
<li>$_layout is name of layout script</li>
<li>$_layout_var is placeholder in layout script to use</li>
</ul>
</li>
<li>_render() handles it
<ul>
<li>if _layout not empty:
<ul>
<li>calls _setLayoutTemplates()</li>
<li>calls _renderLayout()</li>
</ul>
</li>
</ul>
</li>
<li>_setLayoutTemplates()
<ul>
<li>Loops through class stack to determine view script path for layout</li>
</ul>
</li>
<li>_renderLayout()
<ul>
<li>assigns response content to view using _layout_var as key</li>
<li>appends '.php' suffix to _layout to determine view</li>
<li>renders layout view into response</li>
</ul>
</li>
<li>_load()
<ul>
<li>takes spec in _action, which can include a 'layout' key</li>
</ul>
</li>
</ul>

<h3>Pros</h3>
<ul>
<li>Simple and configurable. Easy to disable.</li>
<li>Can specify variable name for placeholder in layout.</li>
</ul>

<h3>Cons</h3>
<ul>
<li>Coupling with controller. Would not work with a dispatch loop.</li>
</ul>

<h2>Rails</h2>
<ul>
<li>URL: <a href="http://ap.rubyonrails.org/classes/ActionController/Layout/ClassMethods.html">http://ap.rubyonrails.org/classes/ActionController/Layout/ClassMethods.html</a></li>
</ul>

<h3>Operation</h3>
<ul>
<li>Object property of controller</li>
<li>By default, looks in views/layouts</li>
<li>By default, looks for
<ul>
<li>layout of same name as controller</li>
<li>layout named application</li>
</ul>
</li>
<li>Specify value for layout as part of class
<ul>
<li>nil means no layout</li>
<li>pass 'layout' key to render()</li>
</ul>
</li>
<li>Inherits variables from controller view object</li>
<li>special variable, content_for_layout is rendered content to use</li>
</ul>

<h3>Pros</h3>
<ul>
<li>Simple to utilize.</li>
<li>Inherits view from application; variable re-use.</li>
<li>Easy to disable <strong>or</strong> enable.</li>
<li>Like the separate directory for layouts vs scripts.</li>
</ul>

<h3>Cons</h3>
<ul>
<li>Controller-based. Wouldn't work with a dispatch loop.</li>
</ul>

<h2>ZF Goals</h2>
<ul>
<li><strong>Must work with a dispatch loop and named response segments.</strong> Since we can forward between actions, or create a loop of actions to dispatch, and because the response content can exist in multiple segments, we have special needs and capabilities other frameworks don't. Rendering must be done <strong>after</strong> the dispatch loop has finished, and should use all content segments.</li>
<li><strong>Must be able to work <em>without</em> MVC.</strong> While the above should be true, Layouts should be available to those not wanting to use the MVC, or using an alternate MVC.</li>
<li><strong>Must be simple to invoke.</strong> A controller should be able to specify a layout at will, and this should be easy to do.</li>
<li><strong>Must be configurable</strong>
<ul>
<li>Must be able to specify which layout to use, but allow for a 'default' layout</li>
<li>Must be able to specify location of layouts</li>
<li>Must be able to specify names of layout variables</li>
</ul>
</li>
<li><strong>Must be able to pick and choose which placeholders to render</strong></li>
<li><span style="text-decoration: line-through;"><strong>Must have a simple API for specifying items to use in the <head> section</strong></span> In discussion with Ralph, we've decided that view variables and the collection helper are the proper solution for this.</li>
<li><strong>Must follow same naming conventions followed in ViewRenderer</strong>
<ul>
<li>naming</li>
<li>suffixes</li>
</ul>
</li>
<li><strong>Must inherit from view set in view renderer (if in use).</strong> This allows view scripts as well as action controllers to set variables to use in the layout.</li>
</ul>

<h3>Implementation</h3>

<h4>Inflector class</h4>
<p>An inflector class that could be used by both the ViewRenderer and Zend_Layout<br />
would need to be created. This would allow specifying:</p>

<ul>
<li>view script suffix</li>
<li>rules for script autodiscovery</li>
<li>rules for normalization of names</li>
</ul>

<h4>Zend_Layout</h4>
<ul>
<li>Accessors
<ul>
<li>layout template; <strong>name</strong> of layout template, without suffix.
<ul>
<li>setLayout()</li>
<li>getLayout()</li>
</ul>
</li>
<li>layout variable name prefix; prefix to use for all variables assigned to view from layout object
<ul>
<li>setLayoutVarPrefix()</li>
<li>getLayoutVarPrefix()</li>
</ul>
</li>
<li>layout path
<ul>
<li>setLayoutPath()</li>
<li>addLayoutPath())</li>
</ul>
</li>
<li>set view object
<ul>
<li>setView()</li>
<li>getView())</li>
</ul>
</li>
<li>layout variable assignment
<ul>
<li>assign()</li>
<li>_<em>get/</em>_set()</li>
</ul>
</li>
</ul>
</li>
<li>render()
<ul>
<li>retrieves view object, according to:
<ul>
<li>internal</li>
<li><span style="text-decoration: line-through;">view renderer</span> The plugin would inject from the ViewRenderer if found.</li>
<li>instantiate own</li>
</ul>
</li>
<li>Clears all script paths</li>
<li>Sets script paths to internal layout path stack</li>
<li>Assigns layout variables to view
<ul>
<li>prepends all variable keys with layout variable name prefix prior to assigning</li>
</ul>
</li>
<li>Determines layout template name (using inflector)</li>
<li>renders layout template</li>
</ul>
</li>
<li>__construct($noMVC)
<ul>
<li>Registers controller plugin with front controller, unless $noMVC true</li>
</ul>
</li>
<li>__construct()
<ul>
<li>Requires a path to layout scripts</li>
<li>Takes optional configuration data and uses to initialize</li>
<li>If a 'useMvc' flag is set (by default), then instantiates and registers controller plugin, and instantiates action helper and registers with it.</li>
</ul>
</li>
<li>getInstance()
<ul>
<li>Used by view helper to retrieve instance of layout class. Constructor sets internal static variable to instance; getInstance() then checks for that; if none is found, throws exception, indicating that Zend_Layout was never initialized</li>
</ul>
</li>
</ul>

<h4>Action helper that proxies to Class instance</h4>
<ul>
<li>use to proxy to accessors</li>
</ul>

<h4>View helper that proxies to Class instance</h4>
<ul>
<li>use to proxy to accessors</li>
</ul>

<h4>Controller plugin (dispatchLoopShutdown())</h4>
<ul>
<li>Checks to see if getLayout() is not empty</li>
<li>Assigns named segments of response object as variables to layout instance</li>
<li>Determines if ViewRenderer has been used, and, if so, passes its view object to the layout object</li>
<li>calls render()</li>
<li>assigns content back into response object</li>
</ul>

<h4>Usage Examples</h4>
<h5>From bootstrap:</h5>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
// Implicitly registers plugin, action helper
$layout = new Zend_Layout('/path/to/views/layouts');
]]></ac:plain-text-body></ac:macro>

<h5>Without MVC</h5>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
$view = new Zend_View(array('basePath' => '/path/to/views/scripts'));
$content = $view->render('foo.phtml');
$layout = new Zend_Layout('/path/to/views/layouts', array(
'useMvc' => false,
'view' => $view
));
$layout->content = $content;
$layout->title = 'Testing Layouts';
echo $layout->render();
]]></ac:plain-text-body></ac:macro>

<h5>Sample layout</h5>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
<html>
<head>
<title><?= $this->layout_title ?></title>
</head>
<body>
<?= $this->layout_content ?>
</body>
</html>
]]></ac:plain-text-body></ac:macro>

<h3>Notes</h3>
<ul>
<li>Would need to be enabled manually, either in bootstrap, a controller, or a plugin.</li>
<li>Can be used without MVC if desired; simply instantiate, use accessors, and call render().</li>
<li>Some on-list have mentioned they'd like support for setting options via config, either to constructor or a setConfig() method</li>
</ul>

<h2>Class Skeletons</h2>
<h3>Zend_View_Helper_Placeholder_Exception</h3>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
class Zend_View_Helper_Placeholder_Exception extends Zend_View_Exception
{}
]]></ac:plain-text-body></ac:macro>

<h3>Zend_View_Helper_Placeholder_Container</h3>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
class Zend_View_Helper_Placeholder_Container extends ArrayObject
{
const SET = 0100;
const APPEND = 0101;

protected $_prefix = '';
protected $_postfix = '';
protected $_separator = '';

protected $_captureLock = false;
protected $_captureType;

/**

  • Set a single value
  • @param mixed $value
  • @return void
    */
    public function set($value)
    Unknown macro: { $this->exchangeArray(array($value)); }

/**

  • Retrieve container value
    *
  • If single element registered, returns that element; otherwise,
  • serializes to array.
  • @return mixed
    */
    public function getValue()
    {
    if (1 == count($this))
    Unknown macro: { return $this[0]; }

return $this->getArrayCopy();
}

/**

  • Set prefix for __toString() serialization
  • @param string $prefix
  • @return Zend_View_Helper_Placeholder_Container
    */
    public function setPrefix($prefix)
    {}

/**

  • Retrieve prefix
  • @return string
    */
    public function getPrefix()
    {}

/**

  • Set postfix for __toString() serialization
  • @param string $postfix
  • @return Zend_View_Helper_Placeholder_Container
    */
    public function setPostfix($postfix)
    {}

/**

  • Retrieve postfix
  • @return string
    */
    public function getPostfix()
    {}

/**

  • Set separator for __toString() serialization
    *
  • Used to implode elements in container
  • @param string $separator
  • @return Zend_View_Helper_Placeholder_Container
    */
    public function setSeparator($separator)
    {}

/**

  • Retrieve separator
  • @return string
    */
    public function getSeparator()
    {}

/**

  • Start capturing content to push into placeholder
  • @param int $type How to capture content into placeholder; append or set
  • @return void
  • @throws Zend_View_Helper_Placeholder_Exception if nested captures detected
    */
    public function captureStart($type = Zend_View_Helper_Placeholder_Container::APPEND)
    {
    if ($this->_captureLock)
    Unknown macro: { throw new Zend_View_Helper_Placeholder_Exception('Cannot nest placeholder captures for the same placeholder'); }

$this->_captureLock = true;
$this->_captureType = $type;
ob_start();
}

/**

  • End content capture
  • @return void
    */
    public function captureEnd()
    Unknown macro: { $data = ob_get_flush(); $this->_captureLock = false; switch ($this->_captureType)
    Unknown macro: { case self}
    }

/**

  • Serialize object to string
  • @return string
    */
    public function __toString()
    Unknown macro: { $items = $this->getArrayCopy(); $return = $this->getPrefix() . implode($this->getSeparator(), $items) . $this->getPostfix(); return $return; }

    }
    ]]></ac:plain-text-body></ac:macro>

<h3>Zend_View_Helper_Placeholder</h3>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
class Zend_View_Helper_Placeholder
{
/**

  • @var Zend_View_Interface
    */
    public $view;

/**

  • Placeholder items
  • @var array
    */
    protected $_items = array();

/**

  • Set view
  • @param Zend_View_Interface $view
  • @return void
    */
    public function setView(Zend_View_Interface $view)
    Unknown macro: { $this->view = $view; }

/**

  • Placeholder helper
  • @param string $name
  • @return Zend_View_Helper_Placeholder_Container
    */
    public function placeholder($name)
    {
    $name = (string) $name;
    if (!isset($this->_items[$name]))
    Unknown macro: { $this->_items[$name] = new Zend_View_Helper_Placeholder_Container(array()); }

return $this->_items[$name];
}
}
]]></ac:plain-text-body></ac:macro>

<h3>Zend_Layout</h3>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
class Zend_Layout
{
/**

  • Set layout script to use
  • @param string $name
  • @return Zend_Layout
    */
    public function setLayout($name)
    {}

/**

  • Get current layout script
  • @return string
    */
    public function getLayout()
    {}

/**

  • Disable layout
    *
  • @return void
    */
    public function disableLayout()
    {}

/**

  • Set layout script path
  • @param string $path
  • @return Zend_Layout
    */
    public function setLayoutPath($path)
    {}

/**

  • Get current layout script path
  • @return string
    */
    public function getLayoutPath()
    {}

/**

  • Set layout variable prefix for injected variables
  • @param string $prefix
  • @return Zend_Layout
    */
    public function setLayoutVarPrefix($prefix)
    {}

/**

  • Get current layout variable prefix
  • @return string
    */
    public function getLayoutVarPrefix()
    {}

/**

  • Set view object
  • @param Zend_View_Interface $view
  • @return Zend_Layout
    */
    public function setView(Zend_View_Interface $view)
    {}

/**

  • Get current view object
  • @return Zend_View_Interface
    */
    public function getView()
    {}

/**

  • Set layout variable
  • @param string $key
  • @param mixed $value
  • @return void
    */
    public function __set($key, $value)
    {}

/**

  • Get layout variable
  • @param string $key
  • @return mixed
    */
    public function __get($key)
    {}

/**

  • Assign one or more layout variables
  • @param mixed $spec Assoc array or string key
  • @param mixed $value Value if $spec is a key
  • @return Zend_Layout
    */
    public function assign($spec, $value = null)
    {}

/**

  • Render layout
    *
  • Sets internal script path as last path on script path stack, assigns
  • layout variables to view, determines layout name using inflector, and
  • renders layout view script.
  • @param mixed $name
  • @return mixed
    */
    public function render($name = null)
    {
    }

/**

  • Constructor
    *
  • Accepts either:
  • - A string path to layouts
  • - An array of options
  • - A Zend_Config object with options
    *
  • Layout script path, either as argument or as key in options, is
  • required.
    *
  • If useMvc flag is false from options, simply sets layout script path.
  • Otherwise, also instantiates and registers action helper and controller
  • plugin.
  • @param mixed $options
  • @return void
    */
    public function __construct($options)
    {
    }
    }
    ]]></ac:plain-text-body></ac:macro>

<h3>Zend_Layout_Controller_Plugin</h3>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
class Zend_Layout_Controller_Plugin extends Zend_Controller_Plugin_Abstract
{
public function __construct(Zend_Layout $layout = null)
{
}

public function setLayout(Zend_Layout $layout)
{
}

public function getLayout()
{
}

/**

  • Renders layout
  • @todo Check for XHR request, check if layout is null, etc.
  • @return void
    */
    public function dispatchLoopShutdown()
    Unknown macro: { $layout = $this->getLayout(); $response = $this->getResponse(); $layout()->assign($response->getBody(true)); $response->setBody($layout->render()); }

    }
    ]]></ac:plain-text-body></ac:macro>

<h3>Zend_Layout_Action_Helper</h3>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
class Zend_Layout_Action_Helper extends Zend_Controller_Action_Helper_Abstract
{
public function setLayout(Zend_Layout $layout)
{
}

public function getLayout()
{
}

public function setLayoutName($name)

Unknown macro: { $this->getLayout()->setLayout($name); }

public function direct($name)

Unknown macro: { return $this->setLayoutName($name); }

}
]]></ac:plain-text-body></ac:macro>

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.