/** * Renders a template. * * 1. This function first looks for a block named "_<view id>_<section>", * 2. if such a block is not found the function will look for a block named * "<type name>_<section>", * 3. the type name is recursively replaced by the parent type name until a * corresponding block is found * * @param FormView $view The form view * @param string $section The section to render (i.e. 'row', 'widget', 'label', ...) * @param array $variables Additional variables * * @return string The html markup * * @throws FormException if no template block exists to render the given section of the view */ protected function render(FormView $view, $section, array $variables = array()) { $mainTemplate = in_array($section, array('widget', 'row')); if ($mainTemplate && $view->isRendered()) { return ''; } if (null === $this->template) { $this->template = reset($this->resources); if (!$this->template instanceof \Twig_Template) { $this->template = $this->environment->loadTemplate($this->template); } } $custom = '_' . $view->getVar('id'); $rendering = $custom . $section; $blocks = $this->getBlocks($view); if (isset($this->varStack[$rendering])) { $typeIndex = $this->varStack[$rendering]['typeIndex'] - 1; $types = $this->varStack[$rendering]['types']; $this->varStack[$rendering]['variables'] = array_replace_recursive($this->varStack[$rendering]['variables'], $variables); } else { $types = $view->getVar('types'); $types[] = $custom; $typeIndex = count($types) - 1; $this->varStack[$rendering] = array('variables' => array_replace_recursive($view->getVars(), $variables), 'types' => $types); } do { $types[$typeIndex] .= '_' . $section; if (isset($blocks[$types[$typeIndex]])) { $this->varStack[$rendering]['typeIndex'] = $typeIndex; // we do not call renderBlock here to avoid too many nested level calls (XDebug limits the level to 100 by default) ob_start(); $this->template->displayBlock($types[$typeIndex], $this->varStack[$rendering]['variables'], $blocks); $html = ob_get_clean(); if ($mainTemplate) { $view->setRendered(); } unset($this->varStack[$rendering]); return $html; } } while (--$typeIndex >= 0); throw new FormException(sprintf('Unable to render the form as none of the following blocks exist: "%s".', implode('", "', array_reverse($types)))); }
/** * Returns the name of the template to use to render the block * * @param FormView $view The form view * @param string $block The name of the block * * @return string|Boolean The template logical name or false when no template is found */ protected function lookupTemplate(FormView $view, $block) { $file = $block . '.html.php'; $id = $view->getVar('id'); if (!isset($this->templates[$id][$block])) { $template = false; $themes = $view->hasParent() ? array() : $this->resources; if (isset($this->themes[$id])) { $themes = array_merge($themes, $this->themes[$id]); } for ($i = count($themes) - 1; $i >= 0; --$i) { if ($this->engine->exists($templateName = $themes[$i] . ':' . $file)) { $template = $templateName; break; } } if (false === $template && $view->hasParent()) { $template = $this->lookupTemplate($view->getParent(), $block); } $this->templates[$id][$block] = $template; } return $this->templates[$id][$block]; }