Browse Source

[Form][FrameworkBundle] Make FormHelper::renderSection() recursively callable, introduce FormHelper::renderBlock()

Victor Berchet 14 năm trước cách đây
mục cha
commit
e09ae3f6a2
29 tập tin đã thay đổi với 96 bổ sung177 xóa
  1. 8 0
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/attributes.html.php
  2. 3 6
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/checkbox_widget.html.php
  3. 3 5
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget.html.php
  4. 2 0
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/container_attributes.html.php
  5. 2 9
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/date_widget.html.php
  6. 1 1
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/datetime_widget.html.php
  7. 1 8
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/email_widget.html.php
  8. 1 1
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_label.html.php
  9. 4 0
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_rows.html.php
  10. 2 4
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_widget.html.php
  11. 0 7
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/file_widget.html.php
  12. 1 1
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_label.html.php
  13. 2 5
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget.html.php
  14. 1 6
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php
  15. 1 7
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php
  16. 1 4
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_widget.html.php
  17. 1 9
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php
  18. 1 9
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php
  19. 1 1
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php
  20. 1 1
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/prototype_row.html.php
  21. 2 5
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/radio_widget.html.php
  22. 1 5
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/repeated_row.html.php
  23. 1 8
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php
  24. 0 9
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/text_widget.html.php
  25. 1 6
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/textarea_widget.html.php
  26. 1 1
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php
  27. 1 7
      src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php
  28. 51 51
      src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php
  29. 1 1
      src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/_text_id_widget.html.php

+ 8 - 0
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/attributes.html.php

@@ -0,0 +1,8 @@
+id="<?php echo $view->escape($id) ?>"
+name="<?php echo $view->escape($full_name) ?>"
+<?php if ($read_only): ?>disabled="disabled" <?php endif ?>
+<?php if ($required): ?>required="required" <?php endif ?>
+<?php if ($max_length): ?>maxlength="<?php echo $view->escape($max_length) ?>" <?php endif ?>
+<?php if ($pattern): ?>pattern="<?php echo $view->escape($pattern) ?>" <?php endif ?>
+<?php foreach($attr as $k => $v) { printf('%s="%s" ', $view->escape($k), $view->escape($v)); } ?>
+

+ 3 - 6
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/checkbox_widget.html.php

@@ -1,8 +1,5 @@
 <input type="checkbox"
-    <?php echo $view['form']->attributes() ?>
-    name="<?php echo $view->escape($full_name) ?>"
-    <?php if ($value): ?>value="<?php echo $view->escape($value) ?>"<?php endif ?>
-    <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-    <?php if ($required): ?>required="required"<?php endif ?>
-    <?php if ($checked): ?>checked="checked"<?php endif ?>
+    <?php echo $view['form']->renderBlock('attributes') ?>
+    <?php if ($value): ?> value="<?php echo $view->escape($value) ?>"<?php endif ?>
+    <?php if ($checked): ?> checked="checked"<?php endif ?>
 />

+ 3 - 5
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget.html.php

@@ -1,15 +1,13 @@
 <?php if ($expanded): ?>
-    <div<?php echo $view['form']->attributes() ?>>
-    <?php foreach ($form as $choice => $child): ?>
+    <div <?php echo $view['form']->renderBlock('container_attributes') ?>>
+    <?php foreach ($form as $child): ?>
         <?php echo $view['form']->widget($child) ?>
         <?php echo $view['form']->label($child) ?>
     <?php endforeach ?>
     </div>
 <?php else: ?>
     <select
-        <?php echo $view['form']->attributes() ?>
-        name="<?php echo $view->escape($full_name) ?>"
-        <?php if ($read_only): ?> disabled="disabled"<?php endif ?>
+        <?php echo $view['form']->renderBlock('attributes') ?>
         <?php if ($multiple): ?> multiple="multiple"<?php endif ?>
     >
         <?php if (null !== $empty_value): ?><option value=""><?php echo $view->escape($view['translator']->trans($empty_value)) ?></option><?php endif; ?>

+ 2 - 0
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/container_attributes.html.php

@@ -0,0 +1,2 @@
+id="<?php echo $view->escape($id) ?>"
+<?php foreach($attr as $k => $v) { printf('%s="%s" ', $view->escape($k), $view->escape($v)); } ?>

+ 2 - 9
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/date_widget.html.php

@@ -1,14 +1,7 @@
 <?php if ($widget == 'single_text'): ?>
-    <input type="text"
-        <?php echo $view['form']->attributes() ?>
-        name="<?php echo $view->escape($full_name) ?>"
-        value="<?php echo $view->escape($value) ?>"
-        <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-        <?php if ($required): ?>required="required"<?php endif ?>
-        <?php if ($max_length): ?>maxlength="<?php echo $max_length ?>"<?php endif ?>
-    />
+    <?php echo $view['form']->widget($form); ?>
 <?php else: ?>
-    <div<?php echo $view['form']->attributes() ?>>
+    <div <?php echo $view['form']->renderBlock('container_attributes') ?>>
         <?php echo str_replace(array('{{ year }}', '{{ month }}', '{{ day }}'), array(
             $view['form']->widget($form['year']),
             $view['form']->widget($form['month']),

+ 1 - 1
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/datetime_widget.html.php

@@ -1,4 +1,4 @@
-<div<?php echo $view['form']->attributes() ?>>
+<div <?php echo $view['form']->renderBlock('container_attributes') ?>>
     <?php echo $view['form']->widget($form['date'])
         . ' '
         . $view['form']->widget($form['time']) ?>

+ 1 - 8
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/email_widget.html.php

@@ -1,8 +1 @@
-<input type="email"
-    <?php echo $view['form']->attributes() ?>
-    name="<?php echo $view->escape($full_name) ?>"
-    value="<?php echo $view->escape($value) ?>"
-    <?php if ($max_length): ?>maxlength="<?php echo $view->escape($max_length) ?>"<?php endif ?>
-    <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-    <?php if ($required): ?>required="required"<?php endif ?>
-/>
+<?php echo $view['form']->widget($form, array('type' => isset($type) ? $type : 'email')) ?>

+ 1 - 1
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_label.html.php

@@ -1 +1 @@
-<label for="<?php echo $view->escape($id) ?>" <?php echo $view['form']->attributes(false) ?>><?php echo $view->escape($view['translator']->trans($label)) ?></label>
+<label for="<?php echo $view->escape($id) ?>" <?php foreach($attr as $k => $v) { printf('%s="%s" ', $view->escape($k), $view->escape($v)); } ?>><?php echo $view->escape($view['translator']->trans($label)) ?></label>

+ 4 - 0
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_rows.html.php

@@ -0,0 +1,4 @@
+<?php echo $view['form']->errors($form) ?>
+<?php foreach ($form as $child) : ?>
+    <?php echo $view['form']->row($child) ?>
+<?php endforeach; ?>

+ 2 - 4
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_widget.html.php

@@ -1,7 +1,5 @@
 <input
-    <?php echo $view['form']->attributes() ?>
-    name="<?php echo $view->escape($full_name) ?>"
+    type="<?php echo isset($type) ? $view->escape($type) : "text" ?>"
     value="<?php echo $view->escape($value) ?>"
-    <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-    <?php if ($required): ?>required="required"<?php endif ?>
+    <?php echo $view['form']->renderBlock('attributes') ?>
 />

+ 0 - 7
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/file_widget.html.php

@@ -1,7 +0,0 @@
-<input type="file"
-    <?php echo $view['form']->attributes() ?>
-    name="<?php echo $view->escape($full_name) ?>"
-    value="<?php echo $view->escape($value) ?>"
-    <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-    <?php if ($required): ?>required="required"<?php endif ?>
-/>

+ 1 - 1
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_label.html.php

@@ -1 +1 @@
-<label <?php echo $view['form']->attributes(false) ?>><?php echo $view->escape($view['translator']->trans($label)) ?></label>
+<label <?php foreach($attr as $k => $v) { printf('%s="%s" ', $view->escape($k), $view->escape($v)); } ?>><?php echo $view->escape($view['translator']->trans($label)) ?></label>

+ 2 - 5
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget.html.php

@@ -1,8 +1,5 @@
-<div<?php echo $view['form']->attributes() ?>>
-    <?php echo $view['form']->errors($form); ?>
-    <?php foreach ($form as $child): ?>
-        <?php echo $view['form']->row($child); ?>
-    <?php endforeach; ?>
+<div <?php echo $view['form']->renderBlock('container_attributes') ?>>
+    <?php echo $view['form']->renderBlock('field_rows') ?>
     <?php echo $view['form']->rest($form) ?>
 </div>
 

+ 1 - 6
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php

@@ -1,6 +1 @@
-<input type="hidden"
-    <?php echo $view['form']->attributes() ?>
-    name="<?php echo $view->escape($full_name) ?>"
-    value="<?php echo $view->escape($value) ?>"
-    <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-/>
+<?php echo $view['form']->widget($form, array('type' => isset($type) ? $type : "hidden")) ?>

+ 1 - 7
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php

@@ -1,7 +1 @@
-<input type="number"
-    <?php echo $view['form']->attributes() ?>
-    name="<?php echo $view->escape($full_name) ?>"
-    value="<?php echo $view->escape($value) ?>"
-    <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-    <?php if ($required): ?>required="required"<?php endif ?>
-/>
+<?php echo $view['form']->widget($form, array('type' => isset($type) ? $type : "number")) ?>

+ 1 - 4
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_widget.html.php

@@ -1,4 +1 @@
-<?php echo str_replace('{{ widget }}',
-    $view['form']->render($form, 'FrameworkBundle:Form:number_widget.html.php'),
-    $money_pattern
-) ?>
+<?php echo str_replace('{{ widget }}', $view['form']->widget($form), $money_pattern) ?>

+ 1 - 9
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php

@@ -1,9 +1 @@
-<input type="text"
-    <?php echo $view['form']->attributes() ?>
-    name="<?php echo $view->escape($full_name) ?>"
-    value="<?php echo $view->escape($value) ?>"
-    <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-    <?php if ($required): ?>required="required"<?php endif ?>
-    <?php if ($max_length): ?>maxlength="<?php echo $max_length ?>"<?php endif ?>
-    <?php if ($pattern): ?>pattern="<?php echo $pattern ?>"<?php endif ?>
-/>
+<?php echo $view['form']->widget($form,  array('type' => isset($type) ? $type : "text")) ?>

+ 1 - 9
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php

@@ -1,9 +1 @@
-<input type="password"
-    <?php echo $view['form']->attributes() ?>
-    name="<?php echo $view->escape($full_name) ?>"
-    value="<?php echo $view->escape($value) ?>"
-    <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-    <?php if ($required): ?>required="required"<?php endif ?>
-    <?php if ($max_length): ?>maxlength="<?php echo $max_length ?>"<?php endif ?>
-    <?php if ($pattern): ?>pattern="<?php echo $pattern ?>"<?php endif ?>
-/>
+<?php echo $view['form']->widget($form,  array('type' => isset($type) ? $type : "password")) ?>

+ 1 - 1
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php

@@ -1 +1 @@
-<?php echo $view['form']->render($form, 'FrameworkBundle:Form:number_widget.html.php') ?> %
+<?php echo $view['form']->widget($form,  array('type' => isset($type) ? $type : "text")) ?> %

+ 1 - 1
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/prototype_row.html.php

@@ -1,3 +1,3 @@
 <script type="text/html" id="<?php echo $view->escape($proto_id) ?>">
-    <?php echo $view->render('FrameworkBundle:Form:field_row.html.php', array('form' => $form)) ?>
+    <?php echo $view['form']->row($form) ?>
 </script>

+ 2 - 5
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/radio_widget.html.php

@@ -1,8 +1,5 @@
 <input type="radio"
-    <?php echo $view['form']->attributes() ?>
-    name="<?php echo $view->escape($full_name) ?>"
+    <?php echo $view['form']->renderBlock('attributes') ?>
     value="<?php echo $view->escape($value) ?>"
-    <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-    <?php if ($required): ?>required="required"<?php endif ?>
-    <?php if ($checked): ?>checked="checked"<?php endif ?>
+    <?php if ($checked): ?> checked="checked"<?php endif ?>
 />

+ 1 - 5
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/repeated_row.html.php

@@ -1,5 +1 @@
-<?php echo $view['form']->errors($form) ?>
-
-<?php foreach ($form as $child): ?>
-    <?php echo $view['form']->row($child); ?>
-<?php endforeach; ?>
+<?php echo $view['form']->renderBlock('field_rows') ?>

+ 1 - 8
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php

@@ -1,8 +1 @@
-<input type="search"
-    <?php echo $view['form']->attributes() ?>
-    name="<?php echo $view->escape($full_name) ?>"
-    value="<?php echo $view->escape($value) ?>"
-    <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-    <?php if ($required): ?>required="required"<?php endif ?>
-    <?php if ($max_length): ?>maxlength="<?php echo $max_length ?>"<?php endif ?>
-/>
+<?php echo $view['form']->widget($form,  array('type' => isset($type) ? $type : "search")) ?>

+ 0 - 9
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/text_widget.html.php

@@ -1,9 +0,0 @@
-<input type="text"
-    <?php echo $view['form']->attributes() ?>
-    name="<?php echo $view->escape($full_name) ?>"
-    value="<?php echo $view->escape($value) ?>"
-    <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-    <?php if ($required): ?>required="required"<?php endif ?>
-    <?php if ($max_length): ?>maxlength="<?php echo $max_length ?>"<?php endif ?>
-    <?php if ($pattern): ?>pattern="<?php echo $pattern ?>"<?php endif ?>
-/>

+ 1 - 6
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/textarea_widget.html.php

@@ -1,6 +1 @@
-<textarea
-    <?php echo $view['form']->attributes() ?>
-    name="<?php echo $view->escape($full_name) ?>"
-    <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-    <?php if ($required): ?>required="required"<?php endif ?>
-><?php echo $view->escape($value) ?></textarea>
+<textarea <?php echo $view['form']->renderBlock('attributes') ?>><?php echo $view->escape($value) ?></textarea>

+ 1 - 1
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php

@@ -1,4 +1,4 @@
-<div<?php echo $view['form']->attributes() ?>>
+<div <?php echo $view['form']->renderBlock('container_attributes') ?>>
     <?php
         // There should be no spaces between the colons and the widgets, that's why
         // this block is written in a single PHP tag

+ 1 - 7
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php

@@ -1,7 +1 @@
-<input type="url"
-    <?php echo $view['form']->attributes() ?>
-    name="<?php echo $view->escape($full_name) ?>"
-    value="<?php echo $view->escape($value) ?>"
-    <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
-    <?php if ($required): ?>required="required"<?php endif ?>
-/>
+<?php echo $view['form']->widget($form,  array('type' => isset($type) ? $type : "url")) ?>

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

@@ -31,12 +31,17 @@ class FormHelper extends Helper
 
     protected $varStack;
 
-    protected $viewStack = array();
+    protected $rendering;
+
+    protected $context;
 
     public function __construct(EngineInterface $engine)
     {
         $this->engine = $engine;
         $this->varStack = new \SplObjectStorage();
+        $this->viewStack = array();
+        $this->rendering = array();
+        $this->context = array();
     }
 
     public function isChoiceGroup($label)
@@ -49,38 +54,6 @@ class FormHelper extends Helper
         return FormUtil::isChoiceSelected($choice, $view->get('value'));
     }
 
-    /**
-     * Renders the attributes for the current view.
-     *
-     * @param Boolean $includeId Whether to render the id attribute
-     *
-     * @return string The HTML markup
-     */
-    public function attributes($includeId = true)
-    {
-        $html = '';
-        $attr = array();
-
-        if (count($this->viewStack) > 0) {
-            $view = end($this->viewStack);
-            $vars = $this->varStack[$view];
-
-            if (isset($vars['attr'])) {
-                $attr = $vars['attr'];
-            }
-
-            if (true === $includeId && isset($vars['id'])) {
-                $attr['id'] = $vars['id'];
-            }
-        }
-
-        foreach ($attr as $k => $v) {
-            $html .= ' '.$this->engine->escape($k).'="'.$this->engine->escape($v).'"';
-        }
-
-        return $html;
-    }
-
     /**
      * Renders the HTML enctype in the form tag, if necessary.
      *
@@ -202,15 +175,34 @@ class FormHelper extends Helper
         }
 
         $template = null;
+
+        $custom = '_'.$view->get('proto_id', $view->get('id'));
         $types = $view->get('types');
-        $types[] = '_'.$view->get('proto_id', $view->get('id'));
+        $types[] = $custom;
+        $rendering = $custom.$section;
 
-        for ($i = count($types) - 1; $i >= 0; $i--) {
-            $types[$i] .= '_'.$section;
-            $template = $this->lookupTemplate($types[$i]);
+        $i = isset($this->rendering[$rendering]) ? $this->rendering[$rendering] - 1 : count ($types) - 1;
+
+        do {
+            $block = $types[$i].'_'.$section;
+            $template = $this->lookupTemplate($block);
 
             if ($template) {
-                $html = $this->render($view, $template, $variables);
+
+                $this->rendering[$rendering] = $i;
+
+                $this->varStack[$view] = array_replace(
+                    $view->all(),
+                    isset($this->varStack[$view]) ? $this->varStack[$view] : array(),
+                    $variables
+                );
+
+                $this->context[] = $this->varStack[$view];
+
+                $html = $this->engine->render($template, $this->varStack[$view]);
+
+                array_pop($this->context);
+                unset($this->varStack[$view], $this->rendering[$rendering]);
 
                 if ($mainTemplate) {
                     $view->setRendered();
@@ -218,27 +210,35 @@ class FormHelper extends Helper
 
                 return $html;
             }
-        }
+        }  while (--$i >= 0);
 
-        throw new FormException(sprintf('Unable to render form as none of the following blocks exist: "%s".', implode('", "', $types)));
+        throw new FormException(sprintf('Unable to render the form as none of the following blocks exist: "%s".', implode('", "', $types)));
     }
 
-    public function render(FormView $view, $template, array $variables = array())
+    /**
+     * Render a block from a form element.
+     *
+     * @param string $name
+     * @param array  $variables Additional variables (those would override the current context)
+     *
+     * @throws FormException if the block is not found
+     * @throws FormException if the method is called out of a form element (no context)
+     */
+    public function renderBlock($name, $variables = array())
     {
-        $this->varStack[$view] = array_replace(
-            $view->all(),
-            isset($this->varStack[$view]) ? $this->varStack[$view] : array(),
-            $variables
-        );
+        if (0 == count($this->context)) {
+            throw new FormException(sprintf('This method should only be called while rendering a form element.', $name));
+        }
 
-        $this->viewStack[] = $view;
+        $template = $this->lookupTemplate($name);
 
-        $html = $this->engine->render($template, $this->varStack[$view]);
+        if (false === $template) {
+            throw new FormException(sprintf('No block "%s" found while rendering the form.', $name));
+        }
 
-        array_pop($this->viewStack);
-        unset($this->varStack[$view]);
+        $variables = array_replace_recursive(end($this->context), $variables);
 
-        return $html;
+        return $this->engine->render($template, $variables);
     }
 
     /**

+ 1 - 1
src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/_text_id_widget.html.php

@@ -1,3 +1,3 @@
 <div id="container">
-    <?php echo $view['form']->render($form, 'FrameworkBundle:Form:text_widget.html.php') ?>
+    <?php echo $view['form']->widget($form) ?>
 </div>