0
votes

What I need

I needed a templating engine for a small site and I decided to try using \Zend\View. I'm not using Zend Framework itself though.

So basically I want to do some data processing in my custom scripts outside of Zend, and then pass the variables into \Zend\View and make it render my templates.

What I've tried

I was referring to the following manual: zend.view.quick-start.html. The basic implementation (where I use \Zend\View\Renderer\PhpRenderer and \Zend\View\Model\ViewModel only) works as expected. But I run into errors when I try something more complex, such as using a common layout.

If I got this right, the \Zend\View\Model\ViewModels can be nested, and I can call the child ones using the predefined placeholders (zend.view.quick-start.html#nesting-view-models). But there should be one primary ViewModel that will serve as a Root (zend.view.quick-start.html#dealing-with-layouts), it will contain the skeleton HTML page with the Doctype and whatever I pass into headTitle(), headMeta() etc.

I tried to create a viewModel, point it to my root layout using setTemplate() and then pass it to the setRoot() function, but it didn't work. I tried to search the code for that function , and I found it in the /Zend/View/Helper/ViewModel.php. It takes an instance of Zend\View\Model\ModelInterface and not an instance of \Zend\View\Model\ViewModel. But when I try to create a new ModelInterface and setTemplate to it, it throws me

Fatal error: Cannot instantiate interface Zend\View\Model\ModelInterface

It becomes overcomplicated, and I can't figure this out.

Here's the code:

<?php
require_once '/path/to/zend/autoloader.php';

$resolver = new \Zend\View\Resolver\TemplatePathStack();
$resolver->addPath('/path/to/views/');

$viewModel = new \Zend\View\Model\ViewModel();
$viewModel->setTemplate('layout.phtml');

//$ModelInterface = new \Zend\View\Model\ModelInterface();
//$ModelInterface->setTemplate('layout.phtml');

// this is the only class that has the setRoot() declared
//$ZendViewHelperViewModel = new \Zend\View\Helper\ViewModel();
//$ZendViewHelperViewModel->setRoot($ModelInterface); 

$renderer = new \Zend\View\Renderer\PhpRenderer();
$renderer->setResolver($resolver); 

//$renderer->layout('layout.phtml');
$renderer->headTitle('Zend');
$renderer->headMeta()->appendHttpEquiv('Content-Type', 'text/html; charset=UTF-8');
$renderer->headLink()->setStylesheet('/test1.css');
$renderer->headLink()->appendStylesheet('/test2.css');
$renderer->headScript()->setFile('/javascript1.js');
$renderer->headScript()->appendFile('/javascript2.js');

$viewModel->setVariable('date', gmdate('r'));

echo $renderer->render($viewModel);
//echo $renderer->render($ZendViewHelperViewModel);

Here's the layout.phtml code:

<?php
$this->headMeta()->appendHttpEquiv('Content-Type', 'text/html;charset=utf-8');
$this->headTitle()->setSeparator(' - ');
?>
<!DOCTYPE html>
<html> 
    <head>
        <?php echo $this->headMeta(); ?> 
        <?php echo $this->headTitle(); ?>
        <?php echo $this->headLink() . "\n" ?>
        <?php echo $this->headscript(). "\n"?>
     </head>
    <body>
        <div id="nav">
            <?php echo $this->layout()->nav ?>
        </div>
        <div id="content">
            <?php echo $this->layout()->content; ?>
        </div>
    </body>
</html>

What I get:

Fatal error: Uncaught exception 'Zend\View\Exception\RuntimeException' with message 'Zend\View\Helper\Layout::getRoot: no view model currently registered as root in renderer' in Zend/View/Helper/Layout.php:64 Stack trace:

0 Zend/View/Helper/Layout.php(37): Zend\View\Helper\Layout->getRoot()

1 [internal function]: Zend\View\Helper\Layout->__invoke()

2 Zend/View/Renderer/PhpRenderer.php(399): call_user_func_array(Object(Zend\View\Helper\Layout), Array)

3 views/layout.phtml(16): Zend\View\Renderer\PhpRenderer->__call('layout', Array)

4 views/layout.phtml(16): Zend\View\Renderer\PhpRenderer->layout()

5 Zend/View/Renderer/PhpRenderer.php(506): include('...')

6 zendviewtest.php(32): Zend\View\Renderer\PhpRenderer->render(Object(Zend\View\Model\ViewModel))

7 {main} thrown in Zend/View/Helper/Layout.php on line 64

I believe this is because of the $this->layout() reference. When I remove that part, it starts working normally.

But I think the $this->layout() is necessary, because it's the natural way of passing the page content. If I remove it and use the plain setVariable('content', ...) it will break the Zend conventions, right?

I'd also like to use some nested layouts like header, footer etc. but I'm not sure how to implement that. I tried searching by the keywords and the error codes, but I can't find anything helpful. Please advise.

UPDATE What would be the best way to handle and display the page contents? Since I can't use the echo $this->layout()->content part suggested in the documentation, what should I replace it with?

1

1 Answers

1
votes

$this->layout() returns the layout view model witch you don't have. to render other view scripts inside another one use partial view helper.

print $this->partial('path/to/other/view/script',array('param1'=>'param1'));

layout in zend framework is defined in the view_manager's configs and handled by the controller, since you are doing these steps manually u don't need a layout... just set your variables like $viewModel->setVariable('param1', 'param1Value'); and use it in the view like $this->param1 ...

But I think the $this->layout() is necessary, because it's the natural way of passing the page content. If I remove it and use the plain setVariable('content', ...) it will break the Zend conventions, right?

you are absolutely WRONG, my application is completly based on zend mvc and i never have used $this->layout(), as i said $this->layout() returns the layout view model witch created by the view manager from the layout.phtml file , the view script that you currently have is the layout. setVariable('content', ...) is the only way you can proceed and there is no other way to do it ...