Note that there are some explanatory texts on larger screens.

plurals
  1. POZend Framework 2 - Output form element, objects as HTML fields
    primarykey
    data
    text
    <h1>Introduction</h1> <p>I'm working through a re-usable Admin module; responsible for handling Authentication, and ACL. This module comes with a base controller that any other module implemented can inherit. So this controller is the <code>Cp\AdminController</code> and isn't accessible, but inherited by all other controllers.</p> <h1>The problem</h1> <p>I have a default/home controller <code>Cp\HomeController</code> that has several actions; login, logout and forgotten/reset password. Currently i'm working on the <code>Cp\HomeController::indexAction</code>. Within this method I simply do the following:</p> <pre><code>// ... controller logic ... public function indexAction() { if ($this-&gt;getAuth()-&gt;hasIdentity()) { # XXX: This is the authorised view/dashboard. } else { # XXX: This is the unauthorised view; login page. $loginForm = new Form\Login(); # XXX: validation, and login form handling here. return array( 'form' =&gt; $loginForm ); } } // ... controller logic ... </code></pre> <p>The issue here is, the <code>Cp\HomeController</code> by default, uses the <code>./module/Cp/view/cp/home/index.phtml</code> template; and looks like:</p> <pre><code>&lt;h1&gt;Authorisation Required&lt;/h1&gt; &lt;section id="admin-login"&gt; &lt;?= $form ?&gt; &lt;/section&gt; </code></pre> <p>I have extended <code>Zend\Form</code> with my own form class <code>./module/Cp/src/Cp/Form.php</code>, this is then extended by any form classes. _Bare in mind, I will move this class into the App so that it's entirely decoupled and completely reusable.</p> <pre><code>&lt;?php // @file: ./module/Cp/src/Cp/Form.php namespace Cp; use Zend\Form\Form as ZendForm; use Zend\Form\Fieldset; use Zend\InputFilter\Input; use Zend\InputFilter\InputFilter; use Zend\View\Model\ViewModel; use Zend\View\Renderer\PhpRenderer; use Zend\View\Resolver; class Form extends ZendForm { /** * Define the form template path. * @var String */ protected $__templatePath; /** * Define the view variables. * @var Array */ protected $__viewVariables = array(); /** * Set the view variable. * @param String $key The index for the variable. * @param Mixed $value The value for the view variable. * @return Cp\Form */ public function set($key, $value) { $this-&gt;__viewVariables[$key] = $value; return $this; } /** * Set the template path. * @param String $path The path for the template file. * @return Cp\Form */ public function setTemplatePath($path) { $this-&gt;__templatePath = $path; return $this; } /** * When the object is buffered in output, we're going to generate the view * and render it. * @return String */ public function __toString() { // Define our template file as form for resolver to map. $map = new Resolver\TemplateMapResolver(array( 'form' =&gt; $this-&gt;__templatePath )); // Define the render instance responsible for rendering the form. $renderer = new PhpRenderer(); $renderer-&gt;setResolver(new Resolver\TemplateMapResolver($map)); // The form view model will generate the form; parsing the vars to it. $view = new ViewModel(); $view-&gt;setVariable('form', $this); $view-&gt;setTemplate('form'); foreach ($this-&gt;__viewVariables as $key =&gt; $value) { if (! property_exists($view, $key)) { $view-&gt;setVariable($key, $value); } } return $renderer-&gt;render($view); } } </code></pre> <p>I inherit this form class in order to create my Login form, a standard e-mail address and password field, something which can be re-used anywhere authentication may occur.</p> <pre><code>&lt;?php namespace Cp\Form; use Zend\Form\Element; class Login extends \Cp\Form { public function __construct($name = 'Login', $action) { // Parse the form name to our parent constructor. parent::__construct($name); // Override default template, defining our form view. $this-&gt;setTemplatePath(MODULE_DIR . 'Cp/view/cp/form/login.phtml'); // Create our form elements, and validation requirements. $email = new Element\Email('email'); $email-&gt;setLabel('E-mail Address'); $password = new Element\Password('password'); $password-&gt;setLabel('Password'); $submit = new Element\Submit('login'); $this-&gt;setAttribute('action', $action) -&gt;setAttribute('method', 'post') -&gt;setAttribute('autocomplete', 'autocomplete') -&gt;add($email) -&gt;add($password) -&gt;add($submit); } } </code></pre> <p>Which the inherited <code>__toString</code> method will take the defined form view, and render it. <em>This</em> is where my problem is, and my question occurs. Within the view (see below) I am trying to create the form, by using the framework, without hard-coding the HTML elements. Since the <code>Cp\Form\Login</code> class could be extended and modified, with a different field, or additional fields, optional or mandatory, or conditionally either.</p> <p>Is there a way to quickly, get Zend to generate the following HTML? Without using partial views or physically writing <code>&lt;input type="&lt;?= ... ?&gt;" name="&lt;?= ... ?&gt;" /&gt;</code>. This is because the attributes can be defined or overwritten inside the controllers, thus, the attributes are unknown at this point; and should be open to flexibility.</p> <pre><code>&lt;section class="authentication-form"&gt; &lt;h2&gt;Authentication Required&lt;/h2&gt; &lt;!-- How-to: Generate the &lt;form&gt; tag and all it's attributes. --&gt; &lt;?= $form-&gt;openTag() ?&gt; &lt;? if ($ipAllowed): ?&gt; &lt;p&gt;Please choose an account to log in through.&lt;/p&gt; &lt;fieldset&gt; &lt;?= $form-&gt;get('email') ?&gt; &lt;/fieldset&gt; &lt;? else: ?&gt; &lt;p&gt;Please log in using your e-mail address and password.&lt;/p&gt; &lt;fieldset&gt; &lt;?= $form-&gt;get('email') ?&gt; &lt;?= $form-&gt;get('password') ?&gt; &lt;/fieldset&gt; &lt;? endif ?&gt; &lt;div class="action"&gt; &lt;!-- How-To: Generate the &lt;input type="submit" name="" ... attributes ... /&gt; &lt;?= $form-&gt;get('login') ?&gt; &lt;/div&gt; &lt;!-- How-To: Generate the form close tag. &lt;?= $form-&gt;closeTag() ?&gt; &lt;/section&gt; </code></pre> <p>Hopefully this is more clearer, than previously.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload