Dojo Dijits in Zend_Layout

Geplaatst in PHP, Webdevelopment, Zend Framework Reeds 8 reacties op dit bericht

A quick tip on using the Dojo implementation in Zend Framework.

Yesterday I was trying to put a borderContainer on my application. Following the code samples in the manual I had it set up pretty fast in my View, but since all pages should utilize this it seemed normal to me that I would integrate this in my Zend_Layout instead of each View separately.

Thus I moved all the code to my Zend_Layout and tada … no more Dojo, it just stopped working. The code below is the (simplified) code of my Zend_Layout at that time.

< ?php
$this->headTitle()->setSeparator(' :: ');
$this->headTitle()->append('Skyrocket Admin');

echo $this->doctype() ?>
<HTML xmlns="http://www.w3.org/1999/xhtml">
<head>
	< ?= $this->headTitle() ?>
	< ?= $this->headLink() ?>
	< ?= $this->headStyle() ?>
	< ?= $this->headScript() ?>
	< ? $this->dojo()->setLocalPath('/admin/scripts/dojo/dojo.js')
	                ->addStyleSheetModule('dijit.themes.tundra');?>
	< ?= $this->dojo() ?>
</head>
<body class="tundra">

< ?
// Load the Dojo helpers
$this->addHelperPath('Zend/Dojo/View/Helper/', 'Zend_Dojo_View_Helper');

// The page layout is a borderContainer, the views
// get rendered in the Center pane
$this->borderContainer()->captureStart('masterLayout',
                                       array('design' => 'headline'),
									   array('style' => 'width: 100%; height: 100%'));

	$this->contentPane()->captureStart('leftPane',
	                                   array('region' => 'left', 'splitter' => true),
									   array('style' => 'width: 200px'));
		?>
		<ul id="navigation" style="margin: 0">
			<li><a href="/admin/pages">Pages</a></li>
			<li><a href="/admin/auth/logout">Logout</a></li>
		</ul>
		< ?
	echo $this->contentPane()->captureEnd('leftPane');

	$this->contentPane()->captureStart('contentPane',
	                                   array('region' => 'center'));
		echo $this->layout()->content;

	echo $this->contentPane()->captureEnd('contentPane');

echo $this->borderContainer()->captureEnd('masterLayout');

?>
</body>
</html>

Back then it was almost 2AM so I didn’t feel like going after the solution. I dropped a post on Zfforums.com and went to sleep. Today on the other hand I felt like digging through the classes that are responsible for creating the dijits and it didn’t took too long to realize what was wrong.

The problem lies in the order of execution, the Zend_Dojo_View_Helper_Dojo class is responsible for outputting the javascript code that converts your basic html elements into Dijits. But in the code sample above I was outputting the dojo() helper before I was actually creating Dijits. Thus the HTML elements got created but the javascript code to convert them into Dijits is never outputted.

The solution is to simply move all your dijit creation code to the top of the page or to move the output of the dojo helper to the bottom. My advice is using the first option, simply because if you output it at the bottom you get to see the un dijitized html for a brief moment which is not nice.

Here is the working code for the borderContainer Layout in a Zend_Layout

< ?php
$this->addHelperPath('Zend/Dojo/View/Helper/', 'Zend_Dojo_View_Helper');
$this->dojo()->setLocalPath('/admin/scripts/dojo/dojo.js')
		     ->addStyleSheetModule('dijit.themes.tundra');

$this->borderContainer()->captureStart('masterLayout',
                                       array('design' => 'headline'),
									   array('style' => 'width: 100%; height: 100%'));

	$this->contentPane()->captureStart('leftPane',
									   array('region' => 'left', 'splitter' => true),
									   array('style' => 'width: 200px'));

		if (Zend_Auth::getInstance()->hasIdentity()):?>
		<ul id="navigation" style="margin: 0">
			<li><a href="/admin/pages">Pages</a></li>
			<li><a href="/admin/auth/logout">Logout</a></li>
		</ul>
		< ?
		endif;

	echo $this->contentPane()->captureEnd('leftPane');

	$this->contentPane()->captureStart('contentPane',
									   array('region' => 'center'),
									   array());

		echo $this->layout()->content;

	echo $this->contentPane()->captureEnd('contentPane');

$data = $this->borderContainer()->captureEnd('masterLayout');

$this->headLink()->appendStylesheet($this->autover('/admin/css/style.css'));

$this->headTitle()->setSeparator(' :: ');
$this->headTitle()->append('Skyrocket Admin');

echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	< ?= $this->headTitle() ?>
	< ?= $this->headLink() ?>
	< ?= $this->headStyle() ?>
	< ?= $this->headScript() ?>
	< ?= $this->dojo() ?>
</head>
<body class="tundra">

	< ?= $data ?>

</body>
</html>

I hope this helps at least some of you out, and if there are any questions or remarks i’d be glad to hear them!


Reacties

  1. 1
    Sat 09 May
    Sosh zei:

    Can you post an example of what you mean by ‘move the output of the dojo helper to the bottom’? I think this is my only option as I’m doing this in a view not the layout.

    Thanks

    11:28
  2. 2
    Sun 31 May
    Johan zei:

    I don’t know what goes wrong, but when I put in the contentPane around “echo $this->layout()->content;” I get a white page. When I look at the source in my browser the code seems ok. When I omit the contentPane, the page renders ok, but my content is under the leftPane.
    Any idea what’s wrong?

    12:41
  3. 3
    Wed 26 Aug
    Steven zei:

    This can be solved better by keeping your layout the same but doing an

    echo $this->dojo();

    at the end of the layout. Thus it calls all the dojo at the end of the page load

    19:12
  4. 4
    Tue 10 Nov
    JavaJohn zei:

    Sorry, but your Zend Code is very messy. Do you really need to use this non-performance Framework? Why not coding directly with you PHP skills? And you really should do some comments on your source for better understanding

    11:37
  5. 5
    Sun 18 Apr
    m4niac zei:

    thank you :)

    08:29
  6. 6
    Sun 15 Aug
    m4niac zei:

    I’m reading this article again after some time…

    The question I don’t think I’ll get an answear too soon from somebody but still have to ask it is the following:
    What if I’m using a layout in which I output $this->layout()->content ? Because from what I’m reading here now seems that you use separate layouts foreach action isn’t it? I don’t think that’s a good practice…

    17:40
  7. 7
    Sun 15 Aug
    m4niac zei:

    ups.. sorry, haven’t seen these line “echo $this->layout()->content;” …

    anyway, i’m looking for a solution that would do that without adding that awful code before outputting dojo… I have a lot of view scripts using dijits so I don’t think that is a very good practice adding all my actions’ view scripts before outputting dojo :|

    17:45
  8. 8
    Sun 15 Aug
    m4niac zei:

    ok so I think your post is a bit outdate and since then ZF 1.10 appeared

    i was using it at the moment of posting that comments but my form wouldn’t show but didn’t pay attention to the fact that dojo loads correctly all that dijits event though they are supposed to be outputed before outputing dojo() – in my case i use a view script which contains these dijits…

    the tabContainer wasn’t outputed because of a stupid dijitParam called ‘doLayout’ which needs to be false… right now i look for more info about it

    http://forums.zend.com/viewtop.....270#p25270 (thanx @ shikala)

    18:33

Reageer

XHTML: Je mag volgende XHTML tags gebruiken: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>