Browse Source

[Form] Never render a view again

If some of the nested views are rendered individually they should not be rendered again when calling form_rest.
A typical would be when some nested file views are rendered, form_rest should not render them again.

It is still possible to render a label once the widget has been rendered. This is for checkboxes and radios
where the widget is typically rendered before the label.
Victor Berchet 14 năm trước cách đây
mục cha
commit
b12b11c131

+ 10 - 3
src/Symfony/Bridge/Twig/Extension/FormExtension.php

@@ -197,6 +197,12 @@ class FormExtension extends \Twig_Extension
      */
      */
     protected function render(FormView $view, $section, array $variables = array())
     protected function render(FormView $view, $section, array $variables = array())
     {
     {
+        $mainTemplate = in_array($section, array('widget', 'row'));
+        if ($mainTemplate && $view->isRendered()) {
+
+                return '';
+        }
+
         $templates = $this->getTemplates($view);
         $templates = $this->getTemplates($view);
         $blocks = $view->get('types');
         $blocks = $view->get('types');
         array_unshift($blocks, '_'.$view->get('id'));
         array_unshift($blocks, '_'.$view->get('id'));
@@ -205,9 +211,6 @@ class FormExtension extends \Twig_Extension
             $block = $block.'_'.$section;
             $block = $block.'_'.$section;
 
 
             if (isset($templates[$block])) {
             if (isset($templates[$block])) {
-                if ('widget' === $section || 'row' === $section) {
-                    $view->setRendered();
-                }
 
 
                 $this->varStack[$view] = array_replace(
                 $this->varStack[$view] = array_replace(
                     $view->all(),
                     $view->all(),
@@ -217,6 +220,10 @@ class FormExtension extends \Twig_Extension
 
 
                 $html = $templates[$block]->renderBlock($block, $this->varStack[$view]);
                 $html = $templates[$block]->renderBlock($block, $this->varStack[$view]);
 
 
+                if ($mainTemplate) {
+                    $view->setRendered();
+                }
+
                 unset($this->varStack[$view]);
                 unset($this->varStack[$view]);
 
 
                 return $html;
                 return $html;

+ 10 - 2
src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php

@@ -107,6 +107,12 @@ class FormHelper extends Helper
 
 
     protected function renderSection(FormView $view, $section, array $variables = array())
     protected function renderSection(FormView $view, $section, array $variables = array())
     {
     {
+        $mainTemplate = in_array($section, array('row', 'widget'));
+        if ($mainTemplate && $view->isRendered()) {
+
+                return '';
+        }
+
         $template = null;
         $template = null;
         $blocks = $view->get('types');
         $blocks = $view->get('types');
         array_unshift($blocks, '_'.$view->get('id'));
         array_unshift($blocks, '_'.$view->get('id'));
@@ -124,11 +130,13 @@ class FormHelper extends Helper
             throw new FormException(sprintf('Unable to render form as none of the following blocks exist: "%s".', implode('", "', $blocks)));
             throw new FormException(sprintf('Unable to render form as none of the following blocks exist: "%s".', implode('", "', $blocks)));
         }
         }
 
 
-        if ('widget' === $section || 'row' === $section) {
+        $html = $this->render($view, $template, $variables);
+
+        if ($mainTemplate) {
             $view->setRendered();
             $view->setRendered();
         }
         }
 
 
-        return $this->render($view, $template, $variables);
+        return $html;
     }
     }
 
 
     public function render(FormView $view, $template, array $variables = array())
     public function render(FormView $view, $template, array $variables = array())

+ 6 - 11
tests/Symfony/Tests/Component/Form/AbstractDivLayoutTest.php

@@ -144,14 +144,11 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest
         $html = $this->renderRest($view);
         $html = $this->renderRest($view);
 
 
         $this->assertMatchesXpath($html,
         $this->assertMatchesXpath($html,
-'/input
-    [@type="hidden"]
-    [@id="parent__token"]
+'/input[@type="hidden"][@id="parent__token"]
 /following-sibling::div
 /following-sibling::div
     [
     [
         ./label[@for="parent_child1"]
         ./label[@for="parent_child1"]
-        /following-sibling::div
-            [@id="parent_child1"]
+        /following-sibling::div[@id="parent_child1"]
             [
             [
                 ./div
                 ./div
                     [
                     [
@@ -160,23 +157,21 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest
                     ]
                     ]
             ]
             ]
     ]
     ]
+
 /following-sibling::div
 /following-sibling::div
     [
     [
         ./label[@for="parent_child2"]
         ./label[@for="parent_child2"]
-        /following-sibling::div
-            [@id="parent_child2"]
+        /following-sibling::div[@id="parent_child2"]
             [
             [
                 ./div
                 ./div
                     [
                     [
                         ./label[@for="parent_child2_field1"]
                         ./label[@for="parent_child2_field1"]
                         /following-sibling::input[@id="parent_child2_field1"]
                         /following-sibling::input[@id="parent_child2_field1"]
                     ]
                     ]
-                /following-sibling::div
-                    [
-                        ./label[@for="parent_child2_field2"]
-                    ]
             ]
             ]
     ]
     ]
+    [count(//label)=4]
+    [count(//input[@type="text"])=2]
 '
 '
         );
         );
     }
     }