Search code examples
phphtmlzend-framework2render

PHP - ZF2 - render template from string variable


i have problem with rendering template in ZF2, where template is in string in variable. There is simple example:

$template = "<div>easy</div>";
$view = new \Zend\View\Model\ViewModel();
$view->setTemplate($template);   

$renderer = new \Zend\View\Renderer\PhpRenderer();
$html = $renderer->render($view);

This code fail on rendering, the renderer think that the template is a path to file. And iam reallz not sure how to tell rendere its a string.

Thx for your time and respond.


Solution

  • You have to extend the PhpRenderer class and override the render method, in such a way that will use the string in the $template as the actual template:

    class MyPhpRenderer extends PhpRenderer {
    public function render($nameOrModel, $values = null)
    {
        if ($nameOrModel instanceof Model) {
            $model       = $nameOrModel;
            $nameOrModel = $model->getTemplate();
            if (empty($nameOrModel)) {
                throw new Exception\DomainException(sprintf(
                    '%s: received View Model argument, but template is empty',
                    __METHOD__
                ));
            }
            $options = $model->getOptions();
            foreach ($options as $setting => $value) {
                $method = 'set' . $setting;
                if (method_exists($this, $method)) {
                    $this->$method($value);
                }
                unset($method, $setting, $value);
            }
            unset($options);
    
            // Give view model awareness via ViewModel helper
            $helper = $this->plugin('view_model');
            $helper->setCurrent($model);
    
            $values = $model->getVariables();
            unset($model);
        }
    
        // find the script file name using the parent private method
        $this->addTemplate($nameOrModel);
        unset($nameOrModel); // remove $name from local scope
    
        $this->__varsCache[] = $this->vars();
    
        if (null !== $values) {
            $this->setVars($values);
        }
        unset($values);
    
        // extract all assigned vars (pre-escaped), but not 'this'.
        // assigns to a double-underscored variable, to prevent naming collisions
        $__vars = $this->vars()->getArrayCopy();
        if (array_key_exists('this', $__vars)) {
            unset($__vars['this']);
        }
        extract($__vars);
        unset($__vars); // remove $__vars from local scope
    
        while ($this->__template = array_pop($this->__templates)) {
            $this->__file = $this->resolver($this->__template);
            try {
                if (!$this->__file) {
                   $this->__content = $this->__template; // this line does what you need
                }else{
                  ob_start();
                  $includeReturn = include $this->__file;
                  $this->__content = ob_get_clean();
                }
            } catch (\Exception $ex) {
                ob_end_clean();
                throw $ex;
            }
            if ($includeReturn === false && empty($this->__content)) {
                throw new Exception\UnexpectedValueException(sprintf(
                    '%s: Unable to render template "%s"; file include failed',
                    __METHOD__,
                    $this->__file
                ));
            }
        }
    
        $this->setVars(array_pop($this->__varsCache));
    
        if ($this->__filterChain instanceof FilterChain) {
            return $this->__filterChain->filter($this->__content); // filter output
        }
    
        return $this->__content;
    }
    }
    

    and then you code should look like:

    $template = "<div>easy</div>";
    $view = new \Zend\View\Model\ViewModel();
    $view->setTemplate($template);   
    
    $renderer = new MyPhpRenderer();
    $html = $renderer->render($view);