Skip to content

Commit f39ce67

Browse files
committed
[Form][FrameworkBundle] PHP theming
1 parent e717c99 commit f39ce67

File tree

8 files changed

+184
-31
lines changed

8 files changed

+184
-31
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<tr>
2+
<td>
3+
<?php echo $view['form']->label($form, isset($label) ? $label : null) ?>
4+
</td>
5+
<td>
6+
<?php echo $view['form']->errors($form) ?>
7+
<?php echo $view['form']->widget($form) ?>
8+
</td>
9+
</tr>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php if (0 < count($errors)) : ?>
2+
<tr>
3+
<td colspan="2">
4+
<?php echo $view['form']->renderBlock('field_errors'); ?>
5+
</td>
6+
</tr>
7+
<?php endif; ?>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<table <?php echo $view['form']->renderBlock('container_attributes') ?>>
2+
<?php echo $view['form']->renderBlock('field_rows') ?>
3+
<?php echo $view['form']->rest($form) ?>
4+
</table>
5+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<tr style="display: none">
2+
<td colspan="2">
3+
<?php echo $view['form']->widget($form) ?>
4+
</td>
5+
</tr>
6+

src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php

Lines changed: 64 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,31 @@
2525
*/
2626
class FormHelper extends Helper
2727
{
28-
static protected $cache = array();
29-
3028
protected $engine;
3129

3230
protected $varStack;
3331

3432
protected $context;
3533

36-
public function __construct(EngineInterface $engine)
34+
protected $resources;
35+
36+
protected $themes;
37+
38+
/**
39+
* Constructor;
40+
*
41+
* @param EngineInterface $engine The templating engine
42+
* @param array $resources An array of theme name
43+
*/
44+
public function __construct(EngineInterface $engine, array $resources = array())
3745
{
3846
$this->engine = $engine;
3947
$this->varStack = array();
4048
$this->context = array();
49+
$this->themes = new \SplObjectStorage();
50+
51+
$this->resources = 0 == count($resources) ? array('FrameworkBundle:Form') : $resources;
52+
4153
}
4254

4355
public function isChoiceGroup($label)
@@ -50,6 +62,19 @@ public function isChoiceSelected(FormView $view, $choice)
5062
return FormUtil::isChoiceSelected($choice, $view->get('value'));
5163
}
5264

65+
/**
66+
* Sets a theme for a given view.
67+
*
68+
* The theme format is "<Bundle>:<Controller>".
69+
*
70+
* @param FormView $view A FormView instance
71+
* @param string|array $resources A theme or an array of theme
72+
*/
73+
public function setTheme(FormView $view, $themes)
74+
{
75+
$this->themes[$view] = (array) $themes;
76+
}
77+
5378
/**
5479
* Renders the HTML enctype in the form tag, if necessary.
5580
*
@@ -178,28 +203,31 @@ protected function renderSection(FormView $view, $section, array $variables = ar
178203
if (isset($this->varStack[$rendering])) {
179204
$typeIndex = $this->varStack[$rendering]['typeIndex'] - 1;
180205
$types = $this->varStack[$rendering]['types'];
181-
$this->varStack[$rendering]['variables'] = array_replace_recursive($this->varStack[$rendering]['variables'], $variables);
206+
$variables = array_replace_recursive($this->varStack[$rendering]['variables'], $variables);
182207
} else {
183208
$types = $view->get('types');
184209
$types[] = $custom;
185210
$typeIndex = count($types) - 1;
186-
$this->varStack[$rendering] = array (
187-
'variables' => array_replace_recursive($view->all(), $variables),
188-
'types' => $types,
189-
);
211+
$variables = array_replace_recursive($view->all(), $variables);
212+
$this->varStack[$rendering]['types'] = $types;
190213
}
191214

215+
$this->varStack[$rendering]['variables'] = $variables;
216+
192217
do {
193218
$types[$typeIndex] .= '_'.$section;
194-
$template = $this->lookupTemplate($types[$typeIndex]);
219+
$template = $this->lookupTemplate($view, $types[$typeIndex]);
195220

196221
if ($template) {
197222

198223
$this->varStack[$rendering]['typeIndex'] = $typeIndex;
199224

200-
$this->context[] = $this->varStack[$rendering]['variables'];
225+
$this->context[] = array(
226+
'variables' => $variables,
227+
'view' => $view,
228+
);
201229

202-
$html = $this->engine->render($template, $this->varStack[$rendering]['variables']);
230+
$html = $this->engine->render($template, $variables);
203231

204232
array_pop($this->context);
205233
unset($this->varStack[$rendering]);
@@ -233,44 +261,52 @@ public function renderBlock($name, $variables = array())
233261
throw new FormException(sprintf('This method should only be called while rendering a form element.', $name));
234262
}
235263

236-
$template = $this->lookupTemplate($name);
264+
$context = end($this->context);
265+
266+
$template = $this->lookupTemplate($context['view'], $name);
237267

238268
if (false === $template) {
239269
throw new FormException(sprintf('No block "%s" found while rendering the form.', $name));
240270
}
241271

242-
$variables = array_replace_recursive(end($this->context), $variables);
272+
$variables = array_replace_recursive($context['variables'], $variables);
243273

244274
return $this->engine->render($template, $variables);
245275
}
246276

247277
/**
248278
* Returns the name of the template to use to render the block
249279
*
250-
* @param string $blockName The name of the block
280+
* @param FormView $view The form view
281+
* @param string $blockName The name of the block
251282
*
252283
* @return string|Boolean The template logical name or false when no template is found
253284
*/
254-
protected function lookupTemplate($blockName)
285+
protected function lookupTemplate(FormView $view, $block)
255286
{
256-
if (isset(self::$cache[$blockName])) {
257-
return self::$cache[$blockName];
258-
}
259287

260-
$template = $blockName.'.html.php';
261-
/*
262-
if ($this->templateDir) {
263-
$template = $this->templateDir.':'.$template;
288+
$file = $block.'.html.php';
289+
290+
$themes = $view->hasParent() ? array() : $this->resources;
291+
292+
if ($this->themes->contains($view)) {
293+
$themes = array_merge($themes, $this->themes[$view]);
264294
}
265-
*/
266-
$template = 'FrameworkBundle:Form:'.$template;
267-
if (!$this->engine->exists($template)) {
268-
$template = false;
295+
296+
for ($i = count($themes) - 1; $i >= 0; --$i) {
297+
298+
$template = $themes[$i].':'.$file;
299+
300+
if ($this->engine->exists($template)) {
301+
return $template;
302+
}
269303
}
270304

271-
self::$cache[$blockName] = $template;
305+
if ($view->hasParent()) {
306+
return $this->lookupTemplate($view->getParent(), $block);
307+
}
272308

273-
return $template;
309+
return false;
274310
}
275311

276312
public function getName()

src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Fixtures/StubTemplateNameParser.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,13 @@ public function __construct($root, $rootCustom)
2929
public function parse($name)
3030
{
3131
$parts = explode(':', $name);
32-
$name = $parts[count($parts)-1];
32+
$name = $parts[count($parts) - 1];
3333

34-
$path = ($name{0} === '_' ? $this->rootCustom : $this->root).'/'.$name;
34+
if ($name[0] == '_') {
35+
$path = $this->rootCustom.'/'.$name;
36+
} else {
37+
$path = $this->root.'/'.$parts[count($parts) - 2].'/'.$name;
38+
}
3539

3640
return new TemplateReference($path, 'php');
3741
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper;
13+
14+
require_once __DIR__.'/Fixtures/StubTemplateNameParser.php';
15+
require_once __DIR__.'/Fixtures/StubTranslator.php';
16+
17+
use Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper;
18+
use Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper;
19+
use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTemplateNameParser;
20+
use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTranslator;
21+
use Symfony\Component\Form\FormView;
22+
use Symfony\Component\Templating\PhpEngine;
23+
use Symfony\Component\Templating\TemplateNameParser;
24+
use Symfony\Component\Templating\Loader\FilesystemLoader;
25+
use Symfony\Tests\Component\Form\AbstractTableLayoutTest;
26+
27+
class FormHelperTableTest extends AbstractTableLayoutTest
28+
{
29+
protected $helper;
30+
31+
protected function setUp()
32+
{
33+
parent::setUp();
34+
35+
$root = realpath(__DIR__.'/../../../Resources/views');
36+
$rootCustom = realpath(__DIR__.'/Resources');
37+
$templateNameParser = new StubTemplateNameParser($root, $rootCustom);
38+
$loader = new FilesystemLoader(array());
39+
$engine = new PhpEngine($templateNameParser, $loader);
40+
41+
$this->helper = new FormHelper($engine, array(
42+
'FrameworkBundle:Form',
43+
'FrameworkBundle:FormTable'
44+
));
45+
46+
$engine->setHelpers(array(
47+
$this->helper,
48+
new TranslatorHelper(new StubTranslator()),
49+
));
50+
}
51+
52+
protected function tearDown()
53+
{
54+
$this->helper = null;
55+
}
56+
57+
protected function renderEnctype(FormView $view)
58+
{
59+
return (string)$this->helper->enctype($view);
60+
}
61+
62+
protected function renderLabel(FormView $view, $label = null, array $vars = array())
63+
{
64+
return (string)$this->helper->label($view, $label, $vars);
65+
}
66+
67+
protected function renderErrors(FormView $view)
68+
{
69+
return (string)$this->helper->errors($view);
70+
}
71+
72+
protected function renderWidget(FormView $view, array $vars = array())
73+
{
74+
return (string)$this->helper->widget($view, $vars);
75+
}
76+
77+
protected function renderRow(FormView $view, array $vars = array())
78+
{
79+
return (string)$this->helper->row($view, $vars);
80+
}
81+
82+
protected function renderRest(FormView $view, array $vars = array())
83+
{
84+
return (string)$this->helper->rest($view, $vars);
85+
}
86+
}

src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ protected function setUp()
3232
{
3333
parent::setUp();
3434

35-
$root = realpath(__DIR__.'/../../../Resources/views/Form');
35+
$root = realpath(__DIR__.'/../../../Resources/views');
3636
$rootCustom = realpath(__DIR__.'/Resources');
3737
$templateNameParser = new StubTemplateNameParser($root, $rootCustom);
3838
$loader = new FilesystemLoader(array());

0 commit comments

Comments
 (0)