diff --git a/src/Symfony/Component/Form/FormRenderer.php b/src/Symfony/Component/Form/FormRenderer.php index 3d6cfa97923e..09b830b43e4f 100644 --- a/src/Symfony/Component/Form/FormRenderer.php +++ b/src/Symfony/Component/Form/FormRenderer.php @@ -87,17 +87,29 @@ public function renderCsrfToken($intention) */ public function renderBlock(FormView $view, $blockName, array $variables = array()) { - if (0 == count($this->variableStack)) { - throw new Exception('This method should only be called while rendering a form element.'); + $resource = $this->engine->getResourceForBlockName($view, $blockName); + + if (!$resource) { + throw new Exception(sprintf('No block "%s" found while rendering the form.', $blockName)); } $viewCacheKey = $view->vars[self::CACHE_KEY_VAR]; - $scopeVariables = end($this->variableStack[$viewCacheKey]); - $resource = $this->engine->getResourceForBlockName($view, $blockName); + // The variables are cached globally for a view (instead of for the + // current suffix) + if (!isset($this->variableStack[$viewCacheKey])) { + $this->variableStack[$viewCacheKey] = array(); - if (!$resource) { - throw new Exception(sprintf('No block "%s" found while rendering the form.', $blockName)); + // The default variable scope contains all view variables, merged with + // the variables passed explicitly to the helper + $scopeVariables = $view->vars; + + $varInit = true; + } else { + // Reuse the current scope and merge it with the explicitly passed variables + $scopeVariables = end($this->variableStack[$viewCacheKey]); + + $varInit = false; } // Merge the passed with the existing attributes @@ -122,6 +134,10 @@ public function renderBlock(FormView $view, $blockName, array $variables = array // Clear the stack array_pop($this->variableStack[$viewCacheKey]); + if ($varInit) { + unset($this->variableStack[$viewCacheKey]); + } + return $html; } @@ -191,6 +207,8 @@ public function searchAndRenderBlock(FormView $view, $blockNameSuffix, array $va // The variables are cached globally for a view (instead of for the // current suffix) if (!isset($this->variableStack[$viewCacheKey])) { + $this->variableStack[$viewCacheKey] = array(); + // The default variable scope contains all view variables, merged with // the variables passed explicitly to the helper $scopeVariables = $view->vars;