PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

Generating Custom Module Layers with Zend_Dojo_BuildLayer

At its simplest, you simply instantiate Zend_Dojo_BuildLayer, feed it the view object and the name of your custom module layer, and have it generate the content of the layer file; it is up to you to then write it to disk.

As an example, let's say you wanted to create the module layer "custom.main". Assuming you follow the recommended project directory structure, and that you are storing your JavaScript files under public/js/, you could do the following:

<?php
$build 
= new Zend_Dojo_BuildLayer(array(
    
'view'      => $view,
    
'layerName' => 'custom.main',
));

$layerContents $build->generateLayerScript();
$filename      APPLICATION_PATH '/../public/js/custom/main.js';
if (!
file_exists(dirname($filename))) {
    
mkdir(dirname($filename));
}
file_put_contents($filename$layerContents);

When should you do the above? For it to work correctly, you need to do it after all view scripts and the layout have been rendered, to ensure that the dojo() helper is fully populated. One easy way to do so is using a front controller plugin, with a dispatchLoopShutdown() hook:

<?php
class App_Plugin_DojoLayer extends Zend_Controller_Plugin_Abstract
{
    public 
$layerScript APPLICATION_PATH '/../public/js/custom/main.js';
    protected 
$_build;

    public function 
dispatchLoopShutdown()
    {
        if (!
file_exists($this->layerScript)) {
            
$this->generateDojoLayer();
        }
    }

    public function 
getBuild()
    {
        
$viewRenderer Zend_Controller_Action_HelperBroker::getStaticHelper(
            
'ViewRenderer'
        
);
        
$viewRenderer->initView();
        if (
null === $this->_build) {
            
$this->_build = new Zend_Dojo_BuildLayer(array(
                
'view'      => $viewRenderer->view,
                
'layerName' => 'custom.main',
            ));
        }
        return 
$this->_build;
    }

    public function 
generateDojoLayer()
    {
        
$build $this->getBuild();
        
$layerContents $build->generateLayerScript();
        if (!
file_exists(dirname($this->layerScript))) {
            
mkdir(dirname($this->layerScript));
        }
        
file_put_contents($this->layerScript$layerContents);
    }
}

Do not generate the layer on every page

It's tempting to generate the layer script on each and every page. However, this is resource intensive, as it must write to the disk on each page. Additionally, since the mtime of the file will keep changing, you will get no benefits of client-side caching. Write the file once.

BuildLayer options

The above functionality will suffice for most situations. For those needing more customization, a variety of options may be invoked.

Setting the view object

While the view object may be passed during instantiation, you may also pass it in to an instance via the setView() method:

<?php
$build
->setView($view);
Setting the layer name

While the layer name may be passed during instantiation, you may also pass it in to an instance via the setLayerName() method:

<?php
$build
->setLayerName("custom.main");
Including onLoad events in the generated layer

dojo.addOnLoad is a useful utility for specifying actions that should trigger when the DOM has finished loading. The dojo() view helper can create these statements via its addOnLoad() and onLoadCapture() methods. In some cases, it makes sense to push these into your layer file instead of rendering them via your view scripts.

By default, these are not rendered; to enable them, pass the consumeOnLoad configuration key during instantiation:

<?php
$build 
= new Zend_Dojo_BuildLayer(array(
    
'view'          => $view,
    
'layerName'     => 'custom.main',
    
'consumeOnLoad' => true,
));

Alternately, you can use the setConsumeOnLoad() method after instantiation:

<?php
$build
->setConsumeOnLoad(true);
Including captured JavaScript in the generated layer

The dojo() view helper includes methods for capturing arbitrary JavaScript to include in the <script> tag containing the various dojo.require and dojo.addOnLoad statements. This can be useful when creating default data stores or globally scoped objects used throughout your application.

By default, these are not rendered; to enable them, pass the consumeJavascript configuration key during instantiation:

<?php
$build 
= new Zend_Dojo_BuildLayer(array(
    
'view'              => $view,
    
'layerName'         => 'custom.main',
    
'consumeJavascript' => true,
));

Alternately, you can use the setConsumeJavascript() method after instantiation:

<?php
$build
->setConsumeJavascript(true);

Zend Framework