ZF2 ViewModel addChild(). How to read it on layout (not template)? - zend-framework

I have problem with Zend Framework 2 and ViewModel with which i can not deal.
I want to do really simple thing, but this framework is not helping with that...
I have for example simple layout:
<html>
<div id="window">
<?php echo $this->window;
// or whatever working....
?>
</div>
<div id="content">
<?php echo $this->content; ?>
</div>
</html>
I want to add content of window in a place, where $this->window is printed.
I have tried by:
$view = new ViewModel();
$window = new ViewModel();
$window->setTemplate('window/window_error222'); // Template with error to include on layout
$view->addChild($window, 'window');
It works fine on content file, but i cannot access 'window' variable in layout file. Is there any solution for that? I dont want to create another template for window div.

I have resolved my problem by this:
$layout = $this->layout();
$layout->addChild($window, 'window');

Related

view render in zend not working properly as expected

My zend layout and scripts are detecting fine. but when in init function of my IndexController I write $this->view->render("header.phtml") It does not show anything one the screen, whereas when I write echo ($this->view->render("header.phtml"); it displays my header.phtml file. Here is my IndexController
class IndexController extends Zend_Controller_Action
{
public function init()
{
$layout = $this->_helper->layout();
//$this->view = $this->getResource('View');
echo ($this->view->render("header.phtml"));
//echo"<pre>";
//var_dump($this->view);
//var_dump(APPICATION_PATH);
}
public function indexAction()
{
// action body
echo "In default index con";
}
}
Also when Igive my url to/mypath/index It does not display the simple line "I'm in index controller" which I'm just echoing. In my bootstrap here is my Zend_Layout settings.
Zend_Loader::loadClass('Zend_View');
$this->view = new Zend_View();
$this->view->setEncoding('UTF-8');
$this->view->setScriptPath($this->root .'/application/default/views/scripts');
$viewRenderer=new Zend_Controller_Action_Helper_ViewRenderer();
// Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
// $view->setScriptPath($this->root.'/'.$theme.'/views/scripts/');
//$view->setScriptPath($this->root.'/application/default/views/scripts/');
$this->view->addScriptPath($this->root.'/application/admin/views/scripts');
$this->view->addScriptPath($this->root.'/application/business/views/scripts');
// $this->view->setHelperPath($this->root .'/application/default/views/helpers');
$this->layout = Zend_Layout::startMvc(
array(
'layoutPath' => $this->root . '/application/default/views/'.$crt_theme.'/layouts',
'layout' => 'layout'
)
);
$this->registry->set("theme", $crt_theme);
variable $crt_theme is set to 'default'.
Rob' answer is correct although you may need some more information as you appear to be working hard at making this complicated. ZF when used as an MVC has a place to put layouts and defaults for using them.
If you are using the Zend_Tool command line interface start with the commmand: zf enable layout and the tool will add the default directory and a default layout.phtml to your project.
in the application.ini it will add the line:
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
and at that path it will add the file layout.phtml
If you need to change the name of the default layout add this line with the name of your script without the .phtml
resources.layout.layout = master
There are as many ways as you can think of to use this file, but here is an example of how I use it.
I like to set my project defaults in my application.ini file so if I need to change anything it's easy.
View Settings
;*************
resources.view[]=
resources.view.charset = "UTF-8"
resources.view.encoding = "UTF-8"
resources.view.doctype = "HTML5"
resources.view.language = "en"
resources.view.contentType = "text/html; charset=UTF-8"
then in my bootstrap I setup the view I want use, I do it here so that if I have multiple layouts (i usually do) it's easy to change css or js files in one place.
protected function _initView() {
//Initialize view
$view = new Zend_View();
$view->addHelperPath('/../library/Application/View/Helper');
$view->doctype(Zend_Registry::get('config')->resources->view->doctype);
$view->headTitle('Our Home');
$view->headMeta()->appendHttpEquiv('Content-Type', Zend_Registry::get(
'config')->resources->view->contentType);
$view->headLink()->setStylesheet('/css/normalize.css');
$view->headLink()->appendStylesheet('/css/blueprint/src/liquid.css');
$view->headLink()->appendStylesheet('/css/blueprint/src/typography.css');
$view->headLink()->appendStylesheet(
'/javascript/mediaelement/build/mediaelementplayer.css');
$view->headLink()->appendStylesheet('/css/main.css');
$view->headLink()->appendStylesheet('/css/nav.css');
$view->headLink()->appendStylesheet('/css/table.css');
//add javascript files
$view->headScript()->setFile('/javascript/mediaelement/build/jquery.js');
$view->headScript()->appendFile('/javascript/modernizr.js');
//add it to the view renderer
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
'ViewRenderer');
$viewRenderer->setView($view);
//Return it, so that it can be stored by the bootstrap
return $view;
}
Notice all of those headLink(), headScript() and docType() entries, these are where the data is set for placeholders, that will be used in the layout.
Now the layout, the actual content from your other action based scripts will typically be rendered by the placeholder $this->layout()->content
<?php
echo $this->doctype() . "\n";//placeholder
?>
<html>
<head>
<title></title>
<?php echo $this->headMeta() . "\n" ?><!-- displays all meta data passed -->
<?php echo $this->headLink() . "\n" ?><!-- displays all links passed -->
<?php echo $this->headscript(). "\n"?><!-- displays all scripts passed -->
</head>
<body>
<section class="container">
<header class="block">
<hgroup id="header" class ="column span-24">
<h1>Our Home</h1>
</hgroup>
<nav>
<div id="nav" class="column span-24">
<?php echo $this->layout()->nav ?> <!-- Custom Placeholder -->
</div>
</nav>
</header>
<section class="block">
<div id="main" class="column span-18 border">
<div id="flash">
<?php
//flash messenger display location
if (count($this->messages) > 0) {
printf("<h3 id='flash'>%s</h3>", $this->messages[0]);
}
?>
</div>
<?php echo $this->layout()->content; ?><!-- Default placeholder, where views are rendered -->
</div>
<aside id="sidebar" class="column span-4 last">
<?php echo $this->layout()->search ?><!-- Custom placeholder -->
<div id="subNav">
<?php echo $this->layout()->subNav ?> <!-- Custom placeholder -->
</div>
<div id="adminMenu">
<h4>Administration Links</h4>
<?php echo $this->layout()->adminMenu ?> <!-- Custom placeholder -->
</div>
</aside>
</section>
<footer class="block">
<div id="footer" class="column span-24">
<p>Created with Zend Framework. &COPY; </p>
</div>
</footer>
</section>
<?php echo $this->inlineScript() ?><!-- placeholder -->
</body>
</html>
Hope this helps!
[Edit]
One more thing, this always seems to be the next question. "How do I change my layout from the default in my controller/action?"
to change the layout from your controller you would typically do it with a preDispatch() method and just pass the name of your new layout to the layout helper.
$this->_helper->layout->setLayout('myOtherLayout');
doing just this will change the layout for every action in the controller. To be more selective you can use a conditional, like:
if ($this->getRequest()->getActionName() == 'player') {
$this->_helper->layout->setLayout('player');//reset layout
//add 2 new headscripts
$this->view->headScript()->appendFile(
'http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js'
);
$this->view->headScript()->appendFile(
'/javascript/mediaplayer/jwplayer.js'
);
}
render() is working as intended; it returns a string that you should then echo.
It is very unusual to be rendering directly in a controller however. At a minimum, you should be rendering your header and footer from views/scripts/index/index.phtml, though using Zend_Layout would be even better. If you are using Zend_Application, then you can start using Zend_Layout simply by adding:
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
to your application/config/application.ini file. You then need to create a application/layouts/scripts/layout.phtml file which could look something like this:
<?php
$this->headMeta()->appendHttpEquiv('Content-Type', 'text/html;charset=utf-8');
$this->headTitle()->setSeparator(' - ');
$this->headTitle('My website');
?>
<!DOCTYPE html>
<html>
<head>
<?php echo $this->headMeta(); ?>
<?php echo $this->headTitle(); ?>
<!-- Other <head> elements and view helpers here -->
</head>
<body>
<div id="content">
<?php echo $this->layout()->content; ?>
</div>
</body>
</html>

Is there a 'kosher' way to display options in a select tag as a list of links, and NOT a drop-down?

My problem is that I am making a dynamic generated form using codeigniter. I need my dynamic results to be made into links. These 'links' are contained within a form and when clicked, should pass an item_id. The displayed link however should portray the item_name. I have both the id and name of every product within a foreach, gathered from a query. The reason I am doing it like this and not having them as a radio/drop-down, is because I'm attempting to make this touchscreen friendly. I need to have them list out as links. I am trying to stay away from javascript on this if I can. Just wondering if anyone had an idea of what I could do here. As I asked in my title, what I am looking for is a way to make form inputs as if they where select/option but listed as links. I also tried them as submit tags, but then I cannot display the name and have the value as the id.
EDIT:
I should also add that $key is the id of each product and $info is the name.
foreach($products as $key => $info):
?>
<div class="field_row clearfix">
<?php
/* NEED THE FORM ELEMENTS HERE */
?>
</div>
<?php
endforeach;
You could use jquery and js metadata to achieve this.
N.B. untested code of the top of my head.
<?php
foreach ($products as $key => $info)
{
?>
<div class="product-link {item_id: <?php echo $key; ?>}">
<?php echo $info; ?>
</div>
<?php
}
?>
<script type=text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
// listen event on drop down
$(".product-link").click(function () {
var item_id = $(this).metadata().item_id;
// do what ever you want here, maybe a redirect
window.location.href = "/products/items/"+item_id;
});
});
/*]]>*/
</script>

Zend Framework - Flashmessenger - Only one character

I have a little problem with FlashMessenger. When I want to retrieve the messages in my layout, it writes the first letter of the message... example "test" displays "t".
I tried a solution posted in this question, but nothing changed for me.
I use php 5.3.6
Here is my code:
In my method :
$message = 'test';
$this->_helper->FlashMessenger($message);
Call in the Layout
<div id="message_box">
<?php echo $this->flashMessages(); ?>
</div>
Can someone help me?
Try this:
In controller:
$this->_helper->FlashMessenger->addMessage("Your message", 'actions');
// you can redirect to another controller ...
$this->view->messages = $this->_helper->FlashMessenger->getMessages('actions');
In phtml file:
<!-- some html code -->
<div id="message_box">
<?php echo $this->messages[0]; ?>
</div>

how do i add a dynamiclally generating dropdown to the layout.phtml in zend framework

i want to add a dropdown menu to my layout .
i have a list of hotels . i want to change the hotel from a dropdown , i need to keep that drop down in my layout.phtml .
problem is hotel list is dynamic.
can i do this , is this possible in zend ,
here is my layout,phtml
i need to add a dropdown to <div class="floatright wid35 textaligncenter padtop5">
<html>
<head>
<?php echo $this->docType(); ?>
<?php echo $this->headTitle(); ?>
<?php echo $this->headScript(); ?>
<?php echo $this->headLink(); ?>
<?php echo $this->headStyle(); ?>
</head>
<body>
<?php echo $this->render('admin/header.phtml'); ?>
<div id="contentColumns" class="columns">
<div id="columnRight" class="column-right"></div>
<div id="columnLeft" class="column-right">
<div class="link-guide">
<div id="breadcrumbs" class="floatleft wid60">
<?php echo $this->navigation()->breadcrumbs()->setLinkLast(false)->setMinDepth(0)->render(); ?>
</div>
<div class="floatright wid35 textaligncenter padtop5">
</div>
</div>
<div class="padding-box">
<?php echo $this->layout()->content; ?>
</div>
</div>
<div class="clear"></div>
</div>
<?php echo $this->render('admin/footer.phtml'); ?>
</body>
</html>
No. Layout files represent the static structure of a page like header and footer and everything you wrap around your dynamic content.
So this is not recommended. However you could solve that implementing the _init method of your main controller and extend any controller with that main controller:
class MainController extends Zend_Action_Controller{
function init(){
$this->view->foo = "Show everywhere!";
}
}
class IndexController extends MainController{
public function indexAction(){
$this->view->bar = "Show only on index/index";
}
}
Or you can use a plugin which would be the more elegant way
class MyPlugin extends Zend_Controller_Plugin_Abstract{
public function preDispatch(Zend_Controller_Request_Abstract $request){
$view = Zend_Controller_Action_HelperBroker::
getStaticHelper('viewRenderer')->view;
$view->foo = "bar";
}
}
and in your bootstrap process register that plugin
Zend_Controller_Front::getInstance()->registerPlugin(new MyPlugin);
You can create preDispatch function in your base controller class.
Then you get hotel list and send it to view:
$this->view->hotels = $hotels;
And in your layout you can parse it as you wish.
I see two issues here:
Using your hotel list in a dropdown suggests that you will have a form My_Form_Hotels extending Zend_Form which accepts the hotel list as a constructor parameter.
Where should you populate the hotel list, instantiate the form, and communicate all this to the view/layout for rendering?
Sounds like a front controller plugin would do the job. Since the layout resource functions as a plugin that runs late in postDispatch(), you need to run yours before that. dispatchLoopStartup() should be fine.
Something like this in library/My/Plugin/HotelForm.php:
class My_Plugin_HotelForm extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
$hotelModel = new My_Model_Hotel();
$hotels = $hotelModel->getAllHotels();
$form = new My_Form_Hotels($hotels);
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$view = $viewRenderer->getView();
$view->hotelForm = $form;
}
}
Then in your layout, simply dump the form using $this->hotelForm.
To enable your plugin, add to application/configs/application.ini:
autoloaderNamespaces[] = 'My_"
resources.frontcontroller.plugins[] = "My_Plugin_HotelForm"

Zend_Nav in zend framework issue getting menu to show up

I have the following problem, using zend framework, specifically zend_nav to create a reusable menu to be passed in via the layout/layout.phtml page. These are the code fragments in their respective files.
first of in application/configs/navigation.xml,
<configdata>
<nav>
<label>Home</label>
<controller>index</controller>
<action>index</action>
<pages>
<add>
<label>Add</label>
<controller>post</controller>
<action>add</action>
</add>
<login>
<label>Admin</label>
<controller>login</controller>
<action>login</action>
</login>
</pages>
</nav>
</configdata>
this is then passed into an object in the Bootstrap.php file(only showing that specific method)
protected function __initNavigation(){
$this->bootstrap('layout');
$layout = $this->getResource('layout');
$view = $layout->getView();
$config = new Zend_Config_Xml(APPLICATION .'/config/navigation.xml', 'nav');
$container = new Zend_Navigation($config);
$view->navigation($container);
}
and then finally in the view layout.phtml, the object should return the menu
<!-- application/layouts/scripts/layout.phtml -->
<?php echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Zend Blog !</title>
<?php echo $this->headLink()->appendStylesheet('/css/global.css')?>
</head>
<body>
<div id="header">
<div id="header-logo">
<b>Blog Me !</b>
</div>
</div>
<div id="menu">
<?php echo $this->navigation()->menu() ?>
</div>
<div id="content">
<?php echo $this->layout()->content ?>
</div>
</body>
</html>
The menu does however not show up when i start up my app in the browser, any ideas as to might have gone wrong, is humbly received.
If you did not name the function __initNavigation with two _ underscores on purpose then you probably expected the code to run automatically. For it to run automatically you need to use a single underscore.
Another possible problem is that _initNavigation runs before _initView as Zend goes through these resources in alphabetical order. But then you need not access $view in this code. You can use the Zend_Registry to store the navigation container:
protected function _initNavigation() {
$config = new Zend_Config_Xml(APPLICATION .'/config/navigation.xml', 'nav');
$container = new Zend_Navigation($config);
Zend_Registry::set('Zend_Navigation', $container);
}
The Zend_Navigation registry entry will be used by default by any navigation helper when no container is specified.
Well i`m impressed, really quick answers, the problem had several aspects, first of you where both right about using a single underscore sign, thanks a lot the both of you !
And as i t turned out, i did misspell,
$config = new Zend_Config_Xml(APPLICATION .'/config/navigation.xml', 'nav');
should be,
$config = new Zend_Config_Xml(APPLICATION_PATH .'/configs/navigation.xml', 'nav');
my fault. And finally a miss in the navigation.xml file, inside the - node, there should be nodes surrounding each of the "page" nodes, that is for instance for the home. It should have
<configdata>
<nav>
<home>
<label>Home</label>
<controller>index</controller>
<action>index</action>
</home>
That was it !
Again, thanks a lot for your hints and tips i the right direction.
Sinc Kalle Johansson
I think your code is correct, just your protected function __initNavigation()
should use just one _ in your _initNavigation()
Then change __initNavigation() to _initNavigation()