Cómo renderizar un formulario en TWIG Drupal 8

En algunas situaciones, necesitamos manejar la estructura de los campos de un formulario custom; este manejo facilita el trabajo por parte de Front para dar estilos a las estructura de los formularios. Así que, si lo que queremos es renderizar o mostrar los cada campo específico de un formulario en una plantilla personalizada TWIG, estos son los pasos:

Para este ejemplo usaremos un módulo dummy: modules/custom/example_fields_form

Creación del módulo example_fields_form.info.yml:

type: module
name: example_fields_form
description: 'some description'
core: 8.x
 

Teniendo nuestro módulo, necesitamos crear un archivo routing, el cual se encargará de llamar y ejecutar nuestro formulario con un requerimiento básico de acceso al contenido, para ello vamos a crear el archivo example_fields_form.routing.yml:

example_fields_form.fields_form:
  path: 'example-fields-form'
  defaults:
    _title: 'example_fields_form'
    _form: '\Drupal\example_fields_form\Form\BuildingForm
  requirements:
    _permission: 'access content'
 

Si nos fijamos en la ruta _form ubicados en el módulo, le hemos dado una ruta /Form/class_name, como hemos definido esta ruta, el archivo routing irá en busca de estos, por lo tanto debemos crear la estructura desde la carpeta raíz del módulo así: /example_fields_form/src/Form/BuildingForm.php. Hemos creado el directorio /src y /Form, además el archivo debe tener la siguiente estructura:

<?php
/**
 * @file
 * Contains \Drupal\example_fields_form\Form\BuildingForm.
 */
namespace Drupal\example_fields_form\Form;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\FormBase;

class BuildingForm extends FormBase {

    public function getFormId() {
        return ‘example_fields_form’;
    }

    public function buildForm(array $form, FormStateInterface $form_state) {
        
    }

    public function submitForm(array &$form, FormStateInterface $form_state) {
        drupal_set_message($this->t('@can_name ,Your application is being submitted!', array('@can_name' => $form_state->getValue('candidate_name'))));
         foreach ($form_state->getValues() as $key => $value) {
           drupal_set_message($key . ': ' . $value);
         }
    }

    public function validateForm(array &$form, FormStateInterface $form_state) {
        $values = $form_state->getValues();
    }
}

En estos momentos ya tenemos la estructura básica para construir nuestro formulario y las funciones básicas submit y validate, ahora sólo necesitamos agregar campos en nuestra función buildForm, para ellos nos vamos a basar en la documentación de drupal.org: https://api.drupal.org/api/drupal/elements/8.2.x Para este ejemplo vamos a usar un campo email y un botón:

$form['email'] = array(
            '#type' => 'email',
            '#placeholder' => t('Email'),
            '#required' => TRUE,
);

//Botón
$form['actions']['continue'] = array(
    '#type' => 'submit',
    '#value' => $this->t('continue'),
    '#attributes' => ['class' => ['act-continue']],
);

Ahora necesitamos decirle a este formulario que va a tener una propiedad #theme para poder renderizar nuestros elementos, para eso ponemos:

$form['#theme'] = 'example-fields-form';
 

El nombre que pongamos, es el mismo que vamos a nombrar nuestro archivo template.

Ahora bien, si necesitamos poner nuestros archivos de estilos custom para este módulo, agregamos:

$form['#attached']['library'][] = example_fields_form/example_fields_form';
 

Ya con esto y teniendo la respectiva estructura para de directorios y el archivo example_fields_form.libraries.yml así:

example_fields_form':
  version: 1.x
  js:
    js/main.js: {}
  css:
    theme:
      css/main.css: {}
Por último retornamos el formulario
 
return $form;
Ahora necesitamos crear nuestro template, para eso vamos a crear un nuevo directorio desde la carpeta raíz del módulo así: /example_fields_form/templates, con el directorio creado vamos a crear nuestro archivo nombrado como lo hicimos en el formulario example-fields-form.html.twig. Ahora tenemos nuestro archivo creado.

Para poder enlazar nuestro Form con el Template, vamos a hacer uso de un hook_theme, para esto debemos crear desde la carpeta raíz un archivo example_fields_form.module y debe quedar así:

function example_fields_form_theme($existing, $type, $theme, $path) {
    return [
        'example-fields-form' => [
            'render element' => 'form',
        ],
    ];
}
Ya podemos hacer uso de nuestro formulario en el archivo.twig, para esto vamos a llamar los campos que hemos creado en el archivo example-fields-form.html.twig así:
 
<article class="example_fields_form">
    <section>
      <div class="content">
        {{ form.email }}
        {{ form.actions.continue }}
      </div>
    </section>
</article>
{{ form.form_build_id }}
{{ form.form_token }}
{{ form.form_id }}
 

Es importante llamar estos últimos campos para que el formulario pueda ser identificado y retornar todos sus datos.

 

Espero les ayude.