How to render a form in custom template in Drupal 8 and 9

Here we are going to discuss how to render custom form in a twig template.

Here first we are rendering entire form in a twig template. And then rendering each field by field in twig template.

Here we have a module dn_studentslist module.

See below steps for creating a form and rendering form in a twig template.

Step 1 

Create below rout in dn_studentslist.routing.yml file  and map to the form StudentForm.

dn_studentslist.add_student:
  path: '/add/students'
  defaults:
    _title: 'Add Students'
    _form: '\Drupal\dn_studentslist\Form\StudentForm'
  requirements:
    _access: 'TRUE'

Step 2

Create a form in module path \Src\Form\StudentForm.php.

<?php

namespace Drupal\dn_studentslist\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Url;
use Drupal\Core\Routing;

/**
 * Provides the form for adding countries.
 */
class StudentForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'dn_student_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    

    
    $form['fname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('First Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	 $form['sname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Second Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	$form['age'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Age'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	 $form['marks'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Marks'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	
    $form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#default_value' => $this->t('Save') ,
    ];
      $form['#theme'] = 'students_add_form';
    return $form;

  }

   /**
   * {@inheritdoc}
   */
  public function validateForm(array & $form, FormStateInterface $form_state) {
        //print_r($form_state->getValues());exit;
		
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array & $form, FormStateInterface $form_state) {

    $get_path_update = explode("/", \Drupal::service('path.current')->getPath());
    

    $field = $form_state->getValues();
	
    $re_url = Url::fromRoute('dn_studentslist.add_student');
   
	$fields["fname"] = $field['fname'];
	$fields["sname"] = $field['sname'];
	$fields["age"] = $field['age'];
	$fields["marks"] = $field['marks'];
	
      
      \Drupal::messenger()->addMessage($this->t('Student data=fname='.$fields["fname"].'=sname='.$fields["sname"].'=age='.$fields["age"].'marks==='.$fields["marks"]));
      
    
      $form_state->setRedirectUrl($re_url);

    
  }

}

Please note we are passing template name in below line before return form variable.

$form[‘#theme’] = ‘students_add_form’;

In this form we are just submitting student name mark and age and displaying submitted data in same form.

Step 3

Create hook_theme function and provide your form template details in your  module file or .theme file as below.

/**
 * @file
 * Implementing our hooks.
 */

/**
 * Implements hook_theme().
 */
function dn_studentslist_theme($existing, $type, $theme, $path) {

  return [
    'students_list' => [
      'variables' => ['students' => [], 'title' => ''],
    ],
	'students_add_form' => [
      'render element' => 'form',
    ],

  ];
}  

Here students_add_form is the form twig template here, students__list is another template.

If you have only one form template, hook_theme return be provided  as below.

return [
	'students_add_form' => [
      'render element' => 'form',
    ],

  ];

Step 4

Create a twig template as below in path /templates/

Here template name will be students-add-form.html.twig

Below code in twig prints entire form in above twig template.

<div class="row custom-form">
  <div class="col-md-6">
    {{ form }}
  </div>
  
</div>

After submission you will get below message in twig template.

You cans see custom-form class in div while inspecting this page.

Step 5

Here we are printing each form field in twig template

So in our students-add-form.html.twig file, first we have to print form hidden fields.

So print below variables first.

{{ form.form_build_id }}

{{ form.form_token }}

{{ form.form_id }}

If we are not printing this , save button of the form will not work.

Next, print each fields in form as below.

{{ form.fname }}

{{ form.sname }}

{{ form.age }}

{{ form.marks }}

{{ form.actions.submit }}

So finaly code in twig template will be as below.

{{ form.form_build_id }}
{{ form.form_token }}
{{ form.form_id }}

<div class="row custom-form">
  <div class="col-md-6">

  </div>
  <div class="col-md-6">
   {{ form.fname }}
   {{ form.sname }}
   {{ form.age }}
   {{ form.marks }}
   {{ form.actions.submit }}
  </div>
</div>

In our StudentForm.php, we have submit button inside  $form[‘actions’] . so we have to use {{ form.actions.submit }} in order to print submit button.

Now we can access the page  /add/students

 

 

So here submit action is returning success message with all details.

Download sample source code here.

 

Get Free E-book
Get a free Ebook on Drupal 8 -theme tutorial
I agree to have my personal information transfered to MailChimp ( more information )
if you like this article Buy me a Coffee this will be an ispiration for me to write articles like this.

You may also like...