Posts Tagged ‘Zend Framework’

Rendering Dojo Stylesheets with a view helper

Tuesday, October 26th, 2010

I’ve been fervently coding Blitzaroo the passed week and I ran into a rather annoying issue when using AJAX with the Zend Framework and Dojo. Take, for example, using AjaxContext to load content for a dijit.layout.TabContainer that houses several dijit.layout.ContentPane(s).

1
2
3
4
5
6
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContexts(array(
    'overview' => 'html',
    'events' => 'html',
    'members' => 'html',
    'recruits' => 'html'))->initContext();

Now then, when the getHref() from a ContentPane is called they load the Ajax data which, in this case, happens to be a dojox.grid.DataGrid. The grid renders just fine without Ajax but when Ajax is used ZF fails to load the proper Stylesheets which need to be loaded manually. I thought, no big deal, I’ll just hit up $this->dojo()->{some method to spit out stylesheets} and to my dismay found that the method is protected. Why? I’m not quite sure. I went ahead and wrote a view helper to fix the problem which is merely a copy/paste of the _renderStylesheet() method but without requiring the Dojo container object. If there is another way around the issue I’m all ears!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class My_View_Helper_DojoStylesheets extends Zend_View_Helper_Abstract
{
        public function dojoStylesheets()
        {
                $dojo = $this->view->dojo();
                $isXhtml = $this->view->doctype()->isXhtml();
                 
                if ($dojo->useCdn()) {
                        $base = $dojo->getCdnBase() . $dojo->getCdnVersion();
                } else {
                        $base = $dojo->_getLocalRelativePath();
                }
                 
                $registeredStylesheets = $dojo->getStylesheetModules();
                foreach ($registeredStylesheets as $stylesheet) {
                        $themeName = substr($stylesheet, strrpos($stylesheet, '.') + 1);
                        $stylesheet = str_replace('.', '/', $stylesheet);
                        $stylesheets[] = $base . '/' . $stylesheet . '/' . $themeName . '.css';
                }
                 
                foreach ($dojo->getStylesheets() as $stylesheet) {
                        $stylesheets[] = $stylesheet;
                }
                 
                if ($dojo->registerDojoStylesheet()) {
                        $stylesheets[] = $base . '/dojo/resources/dojo.css';
                }
                 
                if (empty($stylesheets)) {
                        return '';
                }
                 
                array_reverse($stylesheets);
                $style = '<style type="text/css">' . PHP_EOL . (($isXhtml) ? '<!--' : '<!--') . PHP_EOL;
                foreach ($stylesheets as $stylesheet) {
                        $style .= '    @import "' . $stylesheet . '";' . PHP_EOL;
                }
                $style .= (($isXhtml) ? '-->' : '-->') . PHP_EOL . '</style>';
                 
                return $style;
        }
}

Now my {action}.ajax.phtml script is nice and happy.

1
2
3
4
5
6
7
8
// call the regular members action page - no need to duplicate code!
echo $this->render('team-manager/members.phtml');
 
// inlineScript contains all the formatters for the grid
echo $this->inlineScript();
 
// New view helper to include the data grid CSS files generated by my DataGrid view helper
echo $this->dojoStylesheets();

Zend_Dojo_View_Helper_Dialog

Friday, March 12th, 2010

Quickie

I’m going to make this one short & sweet. I’ve created a view helper for Dialogs (and an extended Dijit view helper).

Zend_Dojo_View_Helper_Dijit_Extended (wtb: namespaces)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<!--?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to  so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Dojo_View_Helper_Dijit_Extended
 * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id$
 */
 
/**
 * Zend_Calendar
 *
 * @category   Zend
 * @package    Zend_Dojo_View_Helper_Dijit_Extended
 * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Dojo_View_Helper_Dijit_Extended extends Zend_Dojo_View_Helper_Dijit
{
        /**
         * Holds the base path for scripts.
         */
        protected static $_scriptBase = null;
 
        /**
         * Dojo for static methods.
         */
        protected static $_dojo = null;
 
        /**
         * View for static methods.
         */
        protected static $_view = null;
 
        /**
         * Static setting for script base.
         * @param string $scriptBase Path to the base script directory.
         */
        public static function setScriptBase($scriptBase)
        {
                self::$_scriptBase = $scriptBase;
        }
 
        /**
         * Static getter for script base.
         * @return string
         */
        public static function getScriptBase()
        {
                return self::$_scriptBase;
        }
 
        /**
         * Adds a stylesheet based on the dojo path (local or cdn).
         * Method is static for situations where you need the stylesheets
         * to render even if even the dijits haven't been called but
         * will during execution (AJAX calls).
         *
         * @param string $stylesheet Path to stylesheet from base path.
         */
        public static function addStylesheet($path)
        {
                // Set static view if necessary
                if (null === self::$_view) {
                        $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
                        self::$_view = $viewRenderer--->view;
                        self::$_dojo = self::$_view->dojo();
                }
 
                // Determine path to use
                if (null === self::getScriptBase()) {
                        if (self::$_dojo->useLocalPath()) {
                                self::setScriptBase(self::$_dojo->getLocalPath());
                        } else {
                                self::setScriptBase(self::$_dojo->getCdnBase() . self::$_dojo->getCdnVersion());
                        }
                }
 
                self::$_dojo->addStylesheet(self::getScriptBase() . $path);
        }
}

Zend_Dojo_View_Helper_Dialog

Pretty simple view helper that renders a dialog using the regular (dijit.Dialog) method or the dojox (dojox.widget.Dialog) method.

Usage

1
2
3
4
5
// Regular dialog
<!--?=$this--->dialog('myDialog', array('title' => 'w00t!', 'content' => 'I am a w00tastic dialog'));?>
 
// Enhanced dojox dialog
<!--?=$this--->dialog('myDialog', array('title' => 'w00t!', 'content' => 'I am a w00tastic dialog'), array('useDojox' => true);?>

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<!--?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to  so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Dojo_View_Helper_Dialog
 * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id$
 */
 
/**
 * Zend_Calendar
 *
 * @category   Zend
 * @package    Zend_Dojo_View_Helper_Dialog
 * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Dojo_View_Helper_Dialog extends Zend_Dojo_View_Helper_Dijit_Extended
{
        const DIALOG_DOJO = 'dijit.Dialog';
        const DIALOG_DOJOX = 'dojox.widget.Dialog';
 
        /**
         * Holds the default dialog type.
         */
        public static $_dialogType = self::DIALOG_DOJO;
 
        /**
         * Sets the default dialog type to use.
         *
         * @param string $dojoType Type of dijit to use.
         */
        public static function setDialogType($dojoType)
        {
                switch ($dojoType) {
                        case self::DIALOG_DOJOX:
                                self::$_dialogType = $dojoType;
                                break;
                        default:
                                self::$_dialogType = self::DIALOG_DOJO;
                                break;
                }
        }
 
        /**
         * DataStore view helper.
         *
         * @param string $id JavaScript id for the dialog.
         * @param array $attribs Attributes for the dialog.
         * @param array $options Options for the dialog.
         */
        public function dialog($id = '', array $attribs = array(), array $options = array())
        {
                if (!$id) {
                        throw new Zend_Exception('Invalid arguments: required jsId.');
                }
 
                // Determine dialog type
                $dialogType = self::$_dialogType;
                if (array_key_exists('useDojox', $options)) {
                        $dialogType = self::DIALOG_DOJOX;
                }
 
                // Require module
                $this--->dojo->requireModule($dialogType);
 
                // Add styles
                if ($dialogType == self::DIALOG_DOJOX) {
                        self::addStylesheet('/dojox/widget/Dialog/Dialog.css');
                }
 
                // Programmatic
                if ($this->_useProgrammatic()) {
                        if (!$this->_useProgrammaticNoScript()) {
                                $this->dojo->addJavascript('var ' . $id . ";\n");
                                $js = $id . ' = ' . 'new ' . $dialogType . '(' . Zend_Json::encode($attribs) . ");";
                                $this->dojo->_addZendLoad("function(){{$js}}");
                        }
                        return '';
                }
 
                // Set extra attribs for declarative
                if (!array_key_exists('id', $attribs)) {
                        $attribs['id'] = $id;
                }
 
                if (!array_key_exists('jsId', $attribs)) {
                        $attribs['jsId'] = $id;
                }
 
                if (!array_key_exists('dojoType', $attribs)) {
                        $attribs['dojoType'] = $dialogType;
                }
 
                if (array_key_exists('content', $attribs)) {
                        $content = $attribs['content'];
                        unset($attribs['content']);
                }
 
                return '<div' .="" $this-="">_htmlAttribs($attribs) . '>' . $content . "</div'>
\n"; } }

Hope it makes life a little easier. Enjoy!