Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationLatte
      • ApplicationTracy
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsLatte
      • Framework
      • HttpTracy
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Templating
    • Utils
  • NetteModule
  • none
  • Tracy

Classes

  • FormMacros
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (http://nette.org)
  5:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  6:  */
  7: 
  8: namespace Nette\Bridges\FormsLatte;
  9: 
 10: use Nette,
 11:     Latte,
 12:     Latte\MacroNode,
 13:     Latte\PhpWriter,
 14:     Latte\CompileException,
 15:     Latte\Macros\MacroSet,
 16:     Nette\Forms\Form;
 17: 
 18: 
 19: /**
 20:  * Macros for Nette\Forms.
 21:  *
 22:  * - {form name} ... {/form}
 23:  * - {input name}
 24:  * - {label name /} or {label name}... {/label}
 25:  * - {inputError name}
 26:  * - {formContainer name} ... {/formContainer}
 27:  *
 28:  * @author     David Grudl
 29:  */
 30: class FormMacros extends MacroSet
 31: {
 32: 
 33:     public static function install(Latte\Compiler $compiler)
 34:     {
 35:         $me = new static($compiler);
 36:         $me->addMacro('form', array($me, 'macroForm'), 'Nette\Bridges\FormsLatte\FormMacros::renderFormEnd($_form)');
 37:         $me->addMacro('formContainer', array($me, 'macroFormContainer'), '$_form = array_pop($_formStack)');
 38:         $me->addMacro('label', array($me, 'macroLabel'), array($me, 'macroLabelEnd'));
 39:         $me->addMacro('input', array($me, 'macroInput'), NULL, array($me, 'macroInputAttr'));
 40:         $me->addMacro('name', array($me, 'macroName'), array($me, 'macroNameEnd'), array($me, 'macroNameAttr'));
 41:         $me->addMacro('inputError', array($me, 'macroInputError'));
 42:     }
 43: 
 44: 
 45:     /********************* macros ****************d*g**/
 46: 
 47: 
 48:     /**
 49:      * {form ...}
 50:      */
 51:     public function macroForm(MacroNode $node, PhpWriter $writer)
 52:     {
 53:         if ($node->prefix) {
 54:             throw new CompileException('Did you mean <form n:name=...> ?');
 55:         }
 56:         $name = $node->tokenizer->fetchWord();
 57:         if ($name === FALSE) {
 58:             throw new CompileException("Missing form name in {{$node->name}}.");
 59:         }
 60:         $node->tokenizer->reset();
 61:         return $writer->write(
 62:             'Nette\Bridges\FormsLatte\FormMacros::renderFormBegin($form = $_form = '
 63:             . ($name[0] === '$' ? 'is_object(%node.word) ? %node.word : ' : '')
 64:             . '$_control[%node.word], %node.array)'
 65:         );
 66:     }
 67: 
 68: 
 69:     /**
 70:      * {formContainer ...}
 71:      */
 72:     public function macroFormContainer(MacroNode $node, PhpWriter $writer)
 73:     {
 74:         $name = $node->tokenizer->fetchWord();
 75:         if ($name === FALSE) {
 76:             throw new CompileException("Missing name in {{$node->name}}.");
 77:         }
 78:         $node->tokenizer->reset();
 79:         return $writer->write(
 80:             '$_formStack[] = $_form; $formContainer = $_form = ' . ($name[0] === '$' ? 'is_object(%node.word) ? %node.word : ' : '') . '$_form[%node.word]'
 81:         );
 82:     }
 83: 
 84: 
 85:     /**
 86:      * {label ...}
 87:      */
 88:     public function macroLabel(MacroNode $node, PhpWriter $writer)
 89:     {
 90:         $words = $node->tokenizer->fetchWords();
 91:         if (!$words) {
 92:             throw new CompileException("Missing name in {{$node->name}}.");
 93:         }
 94:         $name = array_shift($words);
 95:         return $writer->write(
 96:             ($name[0] === '$' ? '$_input = is_object(%0.word) ? %0.word : $_form[%0.word]; if ($_label = $_input' : 'if ($_label = $_form[%0.word]')
 97:                 . '->%1.raw) echo $_label'
 98:                 . ($node->tokenizer->isNext() ? '->addAttributes(%node.array)' : ''),
 99:             $name,
100:             $words ? ('getLabelPart(' . implode(', ', array_map(array($writer, 'formatWord'), $words)) . ')') : 'getLabel()'
101:         );
102:     }
103: 
104: 
105:     /**
106:      * {/label}
107:      */
108:     public function macroLabelEnd(MacroNode $node, PhpWriter $writer)
109:     {
110:         if ($node->content != NULL) {
111:             $node->openingCode = rtrim($node->openingCode, '?> ') . '->startTag() ?>';
112:             return $writer->write('if ($_label) echo $_label->endTag()');
113:         }
114:     }
115: 
116: 
117:     /**
118:      * {input ...}
119:      */
120:     public function macroInput(MacroNode $node, PhpWriter $writer)
121:     {
122:         $words = $node->tokenizer->fetchWords();
123:         if (!$words) {
124:             throw new CompileException("Missing name in {{$node->name}}.");
125:         }
126:         $name = array_shift($words);
127:         return $writer->write(
128:             ($name[0] === '$' ? '$_input = is_object(%0.word) ? %0.word : $_form[%0.word]; echo $_input' : 'echo $_form[%0.word]')
129:                 . '->%1.raw'
130:                 . ($node->tokenizer->isNext() ? '->addAttributes(%node.array)' : ''),
131:             $name,
132:             $words ? 'getControlPart(' . implode(', ', array_map(array($writer, 'formatWord'), $words)) . ')' : 'getControl()'
133:         );
134:     }
135: 
136: 
137:     /**
138:      * deprecated n:input
139:      */
140:     public function macroInputAttr(MacroNode $node, PhpWriter $writer)
141:     {
142:         throw new CompileException('Use n:name instead of n:input.');
143:     }
144: 
145: 
146:     /**
147:      * <form n:name>, <input n:name>, <select n:name>, <textarea n:name> and <label n:name>
148:      */
149:     public function macroNameAttr(MacroNode $node, PhpWriter $writer)
150:     {
151:         $words = $node->tokenizer->fetchWords();
152:         if (!$words) {
153:             throw new CompileException("Missing name in n:{$node->name}.");
154:         }
155:         $name = array_shift($words);
156:         $tagName = strtolower($node->htmlNode->name);
157:         $node->isEmpty = !in_array($tagName, array('form', 'select', 'textarea'), TRUE);
158: 
159:         if ($tagName === 'form') {
160:             return $writer->write(
161:                 'Nette\Bridges\FormsLatte\FormMacros::renderFormBegin($form = $_form = '
162:                     . ($name[0] === '$' ? 'is_object(%0.word) ? %0.word : ' : '')
163:                     . '$_control[%0.word], %1.var, FALSE)',
164:                 $name,
165:                 array_fill_keys(array_keys($node->htmlNode->attrs), NULL)
166:             );
167:         } else {
168:             $method = $tagName === 'label' ? 'getLabel' : 'getControl';
169:             return $writer->write(
170:                 '$_input = ' . ($name[0] === '$' ? 'is_object(%0.word) ? %0.word : ' : '')
171:                     . '$_form[%0.word]; echo $_input->%1.raw'
172:                     . ($node->htmlNode->attrs ? '->addAttributes(%2.var)' : '') . '->attributes()',
173:                 $name,
174:                 $words
175:                     ? $method . 'Part(' . implode(', ', array_map(array($writer, 'formatWord'), $words)) . ')'
176:                     : "{method_exists(\$_input, '{$method}Part')?'{$method}Part':'{$method}'}()",
177:                 array_fill_keys(array_keys($node->htmlNode->attrs), NULL)
178:             );
179:         }
180:     }
181: 
182: 
183:     public function macroName(MacroNode $node, PhpWriter $writer)
184:     {
185:         if (!$node->prefix) {
186:             throw new CompileException("Unknown macro {{$node->name}}, use n:{$node->name} attribute.");
187:         } elseif ($node->prefix !== MacroNode::PREFIX_NONE) {
188:             throw new CompileException("Unknown attribute n:{$node->prefix}-{$node->name}, use n:{$node->name} attribute.");
189:         }
190:     }
191: 
192: 
193:     public function macroNameEnd(MacroNode $node, PhpWriter $writer)
194:     {
195:         preg_match('#^(.*? n:\w+>)(.*)(<[^?].*)\z#s', $node->content, $parts);
196:         if (strtolower($node->htmlNode->name) === 'form') {
197:             $node->content = $parts[1] . $parts[2] . '<?php Nette\Bridges\FormsLatte\FormMacros::renderFormEnd($_form, FALSE) ?>' . $parts[3];
198:         } else { // select, textarea
199:             $node->content = $parts[1] . '<?php echo $_input->getControl()->getHtml() ?>' . $parts[3];
200:         }
201:     }
202: 
203: 
204:     /**
205:      * {inputError ...}
206:      */
207:     public function macroInputError(MacroNode $node, PhpWriter $writer)
208:     {
209:         $name = $node->tokenizer->fetchWord();
210:         if (!$name) {
211:             return $writer->write('echo %escape($_input->getError())');
212:         } elseif ($name[0] === '$') {
213:             return $writer->write('$_input = is_object(%0.word) ? %0.word : $_form[%0.word]; echo %escape($_input->getError())', $name);
214:         } else {
215:             return $writer->write('echo %escape($_form[%0.word]->getError())', $name);
216:         }
217:     }
218: 
219: 
220:     /********************* run-time writers ****************d*g**/
221: 
222: 
223:     /**
224:      * Renders form begin.
225:      * @return void
226:      */
227:     public static function renderFormBegin(Form $form, array $attrs, $withTags = TRUE)
228:     {
229:         foreach ($form->getControls() as $control) {
230:             $control->setOption('rendered', FALSE);
231:         }
232:         $el = $form->getElementPrototype();
233:         $el->action = $action = (string) $el->action;
234:         $el = clone $el;
235:         if (strcasecmp($form->getMethod(), 'get') === 0) {
236:             $el->action = preg_replace('~\?[^#]*~', '', $el->action, 1);
237:         }
238:         $el->addAttributes($attrs);
239:         echo $withTags ? $el->startTag() : $el->attributes();
240:     }
241: 
242: 
243:     /**
244:      * Renders form end.
245:      * @return string
246:      */
247:     public static function renderFormEnd(Form $form, $withTags = TRUE)
248:     {
249:         $s = '';
250:         if (strcasecmp($form->getMethod(), 'get') === 0) {
251:             foreach (preg_split('#[;&]#', parse_url($form->getElementPrototype()->action, PHP_URL_QUERY), NULL, PREG_SPLIT_NO_EMPTY) as $param) {
252:                 $parts = explode('=', $param, 2);
253:                 $name = urldecode($parts[0]);
254:                 if (!isset($form[$name])) {
255:                     $s .= Nette\Utils\Html::el('input', array('type' => 'hidden', 'name' => $name, 'value' => urldecode($parts[1])));
256:                 }
257:             }
258:         }
259: 
260:         foreach ($form->getComponents(TRUE, 'Nette\Forms\Controls\HiddenField') as $control) {
261:             if (!$control->getOption('rendered')) {
262:                 $s .= $control->getControl();
263:             }
264:         }
265: 
266:         if (iterator_count($form->getComponents(TRUE, 'Nette\Forms\Controls\TextInput')) < 2) {
267:             $s .= '<!--[if IE]><input type=IEbug disabled style="display:none"><![endif]-->';
268:         }
269: 
270:         echo ($s ? "<div>$s</div>\n" : '') . ($withTags ? $form->getElementPrototype()->endTag() . "\n" : '');
271:     }
272: 
273: }
274: 
Nette 2.2.2 API API documentation generated by ApiGen 2.8.0