Skip to content

Commit b4e3925

Browse files
committed
FormMacros: allows forms nesting (it is prohibited by HTML)
1 parent 7deef08 commit b4e3925

File tree

5 files changed

+104
-98
lines changed

5 files changed

+104
-98
lines changed

src/Bridges/FormsLatte/FormMacros.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ class FormMacros extends MacroSet
3131
public static function install(Latte\Compiler $compiler)
3232
{
3333
$me = new static($compiler);
34-
$me->addMacro('form', [$me, 'macroForm'], 'echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd($this->global->formsCurrent)');
35-
$me->addMacro('formContainer', [$me, 'macroFormContainer'], '$formContainer = $_form = $this->global->formsCurrent = array_pop($this->global->formsStack)');
34+
$me->addMacro('form', [$me, 'macroForm'], 'echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack));');
35+
$me->addMacro('formContainer', [$me, 'macroFormContainer'], 'array_pop($this->global->formsStack); $formContainer = $_form = end($this->global->formsStack)');
3636
$me->addMacro('label', [$me, 'macroLabel'], [$me, 'macroLabelEnd'], NULL, self::AUTO_EMPTY);
3737
$me->addMacro('input', [$me, 'macroInput']);
3838
$me->addMacro('name', [$me, 'macroName'], [$me, 'macroNameEnd'], [$me, 'macroNameAttr']);
@@ -61,7 +61,7 @@ public function macroForm(MacroNode $node, PhpWriter $writer)
6161
$node->replaced = true;
6262
$node->tokenizer->reset();
6363
return $writer->write(
64-
'echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $_form = $this->global->formsCurrent = '
64+
'echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $_form = $this->global->formsStack[] = '
6565
. ($name[0] === '$' ? 'is_object(%node.word) ? %node.word : ' : '')
6666
. '$this->global->uiControl[%node.word], %node.array)'
6767
);
@@ -82,9 +82,9 @@ public function macroFormContainer(MacroNode $node, PhpWriter $writer)
8282
}
8383
$node->tokenizer->reset();
8484
return $writer->write(
85-
'$this->global->formsStack[] = $this->global->formsCurrent; $formContainer = $_form = $this->global->formsCurrent = '
85+
'$this->global->formsStack[] = $formContainer = $_form = '
8686
. ($name[0] === '$' ? 'is_object(%node.word) ? %node.word : ' : '')
87-
. '$this->global->formsCurrent[%node.word]'
87+
. 'end($this->global->formsStack)[%node.word]'
8888
);
8989
}
9090

@@ -104,7 +104,7 @@ public function macroLabel(MacroNode $node, PhpWriter $writer)
104104
$node->replaced = true;
105105
$name = array_shift($words);
106106
return $writer->write(
107-
($name[0] === '$' ? '$_input = is_object(%0.word) ? %0.word : $this->global->formsCurrent[%0.word]; if ($_label = $_input' : 'if ($_label = $this->global->formsCurrent[%0.word]')
107+
($name[0] === '$' ? '$_input = is_object(%0.word) ? %0.word : end($this->global->formsStack)[%0.word]; if ($_label = $_input' : 'if ($_label = end($this->global->formsStack)[%0.word]')
108108
. '->%1.raw) echo $_label'
109109
. ($node->tokenizer->isNext() ? '->addAttributes(%node.array)' : ''),
110110
$name,
@@ -140,7 +140,7 @@ public function macroInput(MacroNode $node, PhpWriter $writer)
140140
$node->replaced = true;
141141
$name = array_shift($words);
142142
return $writer->write(
143-
($name[0] === '$' ? '$_input = is_object(%0.word) ? %0.word : $this->global->formsCurrent[%0.word]; echo $_input' : 'echo $this->global->formsCurrent[%0.word]')
143+
($name[0] === '$' ? '$_input = is_object(%0.word) ? %0.word : end($this->global->formsStack)[%0.word]; echo $_input' : 'echo end($this->global->formsStack)[%0.word]')
144144
. '->%1.raw'
145145
. ($node->tokenizer->isNext() ? '->addAttributes(%node.array)' : ''),
146146
$name,
@@ -164,7 +164,7 @@ public function macroNameAttr(MacroNode $node, PhpWriter $writer)
164164

165165
if ($tagName === 'form') {
166166
return $writer->write(
167-
'echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $_form = $this->global->formsCurrent = '
167+
'echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $_form = $this->global->formsStack[] = '
168168
. ($name[0] === '$' ? 'is_object(%0.word) ? %0.word : ' : '')
169169
. '$this->global->uiControl[%0.word], %1.var, FALSE)',
170170
$name,
@@ -174,7 +174,7 @@ public function macroNameAttr(MacroNode $node, PhpWriter $writer)
174174
$method = $tagName === 'label' ? 'getLabel' : 'getControl';
175175
return $writer->write(
176176
'$_input = ' . ($name[0] === '$' ? 'is_object(%0.word) ? %0.word : ' : '')
177-
. '$this->global->formsCurrent[%0.word]; echo $_input->%1.raw'
177+
. 'end($this->global->formsStack)[%0.word]; echo $_input->%1.raw'
178178
. ($node->htmlNode->attrs ? '->addAttributes(%2.var)' : '') . '->attributes()',
179179
$name,
180180
$method . 'Part(' . implode(', ', array_map([$writer, 'formatWord'], $words)) . ')',
@@ -198,7 +198,7 @@ public function macroNameEnd(MacroNode $node, PhpWriter $writer)
198198
{
199199
$tagName = strtolower($node->htmlNode->name);
200200
if ($tagName === 'form') {
201-
$node->innerContent .= '<?php echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd($this->global->formsCurrent, FALSE) ?>';
201+
$node->innerContent .= '<?php echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack), FALSE) ?>';
202202
} elseif ($tagName === 'label') {
203203
if ($node->htmlNode->isEmpty) {
204204
$node->innerContent = "<?php echo \$_input->getLabelPart()->getHtml() ?>";
@@ -226,9 +226,9 @@ public function macroInputError(MacroNode $node, PhpWriter $writer)
226226
if (!$name) {
227227
return $writer->write('echo %escape($_input->getError())');
228228
} elseif ($name[0] === '$') {
229-
return $writer->write('$_input = is_object(%0.word) ? %0.word : $this->global->formsCurrent[%0.word]; echo %escape($_input->getError())', $name);
229+
return $writer->write('$_input = is_object(%0.word) ? %0.word : end($this->global->formsStack)[%0.word]; echo %escape($_input->getError())', $name);
230230
} else {
231-
return $writer->write('echo %escape($this->global->formsCurrent[%0.word]->getError())', $name);
231+
return $writer->write('echo %escape(end($this->global->formsStack)[%0.word]->getError())', $name);
232232
}
233233
}
234234

tests/Forms.Latte/expected/FormMacros.button.phtml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,22 @@ class Template%a% extends Latte\Template
77
function render()
88
{
99
%A%<form<?php
10-
echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $_form = $this->global->formsCurrent = $this->global->uiControl["myForm"], array (
10+
echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $_form = $this->global->formsStack[] = $this->global->uiControl["myForm"], array (
1111
), FALSE) ?>>
1212
<button<?php
13-
$_input = $this->global->formsCurrent["send"];
13+
$_input = end($this->global->formsStack)["send"];
1414
echo $_input->getControlPart()->attributes() ?>>
1515
description of button
1616
</button>
1717

1818
<button<?php
19-
$_input = $this->global->formsCurrent["send"];
19+
$_input = end($this->global->formsStack)["send"];
2020
echo $_input->getControlPart()->attributes() ?>></button>
2121

2222
<button<?php
23-
$_input = $this->global->formsCurrent["send"];
23+
$_input = end($this->global->formsStack)["send"];
2424
echo $_input->getControlPart()->attributes() ?>><?php echo htmlspecialchars($_input->caption) ?></button>
25-
<?php echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd($this->global->formsCurrent, FALSE) ?></form>
25+
<?php echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack), FALSE) ?></form>
2626
<?php
2727
}
2828

tests/Forms.Latte/expected/FormMacros.formContainer.phtml

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,53 +7,51 @@ class Template%a% extends Latte\Template
77
function render()
88
{
99
%A%
10-
echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $_form = $this->global->formsCurrent = $this->global->uiControl["myForm"], []) ?>
10+
echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $_form = $this->global->formsStack[] = $this->global->uiControl["myForm"], []) ?>
1111

1212
<table>
1313
<tr>
14-
<th><?php if ($_label = $this->global->formsCurrent["input1"]->getLabel()) echo $_label ?></th>
15-
<td><?php echo $this->global->formsCurrent["input1"]->getControl() ?></td>
14+
<th><?php if ($_label = end($this->global->formsStack)["input1"]->getLabel()) echo $_label ?></th>
15+
<td><?php echo end($this->global->formsStack)["input1"]->getControl() ?></td>
1616
</tr>
17-
<?php
18-
$this->global->formsStack[] = $this->global->formsCurrent;
19-
$formContainer = $_form = $this->global->formsCurrent = $this->global->formsCurrent["cont1"] ?>
17+
<?php $this->global->formsStack[] = $formContainer = $_form = end($this->global->formsStack)["cont1"] ?>
2018
<tr>
21-
<th><?php if ($_label = $this->global->formsCurrent["input2"]->getLabel()) echo $_label ?></th>
22-
<td><?php echo $this->global->formsCurrent["input2"]->getControl() ?></td>
19+
<th><?php if ($_label = end($this->global->formsStack)["input2"]->getLabel()) echo $_label ?></th>
20+
<td><?php echo end($this->global->formsStack)["input2"]->getControl() ?></td>
2321
</tr>
2422
<tr>
25-
<th><?php if ($_label = $this->global->formsCurrent["input3"]->getLabel()) echo $_label ?></th>
26-
<td><?php echo $this->global->formsCurrent["input3"]->getControl() ?></td>
23+
<th><?php if ($_label = end($this->global->formsStack)["input3"]->getLabel()) echo $_label ?></th>
24+
<td><?php echo end($this->global->formsStack)["input3"]->getControl() ?></td>
2725
</tr>
2826
<tr>
2927
<th>Checkboxes</th>
3028
<td>
31-
<?php
32-
$this->global->formsStack[] = $this->global->formsCurrent;
33-
$formContainer = $_form = $this->global->formsCurrent = $this->global->formsCurrent["cont2"] ?> <ol>
29+
<?php $this->global->formsStack[] = $formContainer = $_form = end($this->global->formsStack)["cont2"] ?> <ol>
3430
<?php
3531
$iterations = 0;
3632
if (isset($this->params['name'])) trigger_error('Variable $name overwritten in foreach.');
3733
if (isset($this->params['field'])) trigger_error('Variable $field overwritten in foreach.');
3834
foreach ($formContainer->controls AS $name => $field) {
3935
?> <li><?php
40-
$_input = is_object($field) ? $field : $this->global->formsCurrent[$field];
36+
$_input = is_object($field) ? $field : end($this->global->formsStack)[$field];
4137
echo $_input->getControl() ?></li>
4238
<?php
4339
$iterations++;
4440
}
4541
?> </ol>
46-
<?php $formContainer = $_form = $this->global->formsCurrent = array_pop($this->global->formsStack) ?>
42+
<?php
43+
array_pop($this->global->formsStack);
44+
$formContainer = $_form = end($this->global->formsStack) ?>
4745
</td>
4846
</tr>
4947
<tr>
50-
<th><?php if ($_label = $this->global->formsCurrent["input7"]->getLabel()) echo $_label ?></th>
51-
<td><?php echo $this->global->formsCurrent["input7"]->getControl() ?></td>
48+
<th><?php if ($_label = end($this->global->formsStack)["input7"]->getLabel()) echo $_label ?></th>
49+
<td><?php echo end($this->global->formsStack)["input7"]->getControl() ?></td>
5250
</tr>
5351
<?php
54-
$formContainer = $_form = $this->global->formsCurrent = array_pop($this->global->formsStack);
55-
$this->global->formsStack[] = $this->global->formsCurrent;
56-
$formContainer = $_form = $this->global->formsCurrent = $this->global->formsCurrent["items"] ?>
52+
array_pop($this->global->formsStack);
53+
$formContainer = $_form = end($this->global->formsStack);
54+
$this->global->formsStack[] = $formContainer = $_form = end($this->global->formsStack)["items"] ?>
5755
<tr>
5856
<th>Items</th>
5957
<td>
@@ -63,24 +61,28 @@ class Template%a% extends Latte\Template
6361
if (isset($this->params['item'])) trigger_error('Variable $item overwritten in foreach.');
6462
foreach ($items as $item) {
6563
if (!isset($formContainer[$item])) continue;
66-
$this->global->formsStack[] = $this->global->formsCurrent;
67-
$formContainer = $_form = $this->global->formsCurrent = is_object($item) ? $item : $this->global->formsCurrent[$item] ?> <?php
68-
echo $this->global->formsCurrent["input"]->getControl() ?>
64+
$this->global->formsStack[] = $formContainer = $_form = is_object($item) ? $item : end($this->global->formsStack)[$item] ?> <?php
65+
echo end($this->global->formsStack)["input"]->getControl() ?>
6966

7067
<?php
71-
$formContainer = $_form = $this->global->formsCurrent = array_pop($this->global->formsStack);
68+
array_pop($this->global->formsStack);
69+
$formContainer = $_form = end($this->global->formsStack);
7270
$iterations++;
7371
}
7472
?>
7573
</td>
7674
</tr>
77-
<?php $formContainer = $_form = $this->global->formsCurrent = array_pop($this->global->formsStack) ?>
75+
<?php
76+
array_pop($this->global->formsStack);
77+
$formContainer = $_form = end($this->global->formsStack) ?>
7878
<tr>
79-
<th><?php if ($_label = $this->global->formsCurrent["input8"]->getLabel()) echo $_label ?></th>
80-
<td><?php echo $this->global->formsCurrent["input8"]->getControl() ?></td>
79+
<th><?php if ($_label = end($this->global->formsStack)["input8"]->getLabel()) echo $_label ?></th>
80+
<td><?php echo end($this->global->formsStack)["input8"]->getControl() ?></td>
8181
</tr>
8282
</table>
83-
<?php echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd($this->global->formsCurrent) ?>
83+
<?php
84+
echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack));
85+
?>
8486

8587
<?php
8688
}

0 commit comments

Comments
 (0)