drupal|July 23, 2020|3 min read

Drupal 8 - How to Theme Form and its Fields with reordering fields

TL;DR

Theme Drupal 8 forms by overriding individual field twig templates or by creating a custom form template to reorder and style fields with CSS classes.

Drupal 8 - How to Theme Form and its Fields with reordering fields

Introduction

In this post, we will see how to theme form and its fields. Assumming we are having a content type: Article, and it is having following fields:

  • Title
  • Body
  • Tags

Method-1 Theme Fields by their individual Twig file

In this method, we will see over-riding twig files. And, will put some css classes over form fields.

You need to do some pre-requisites here:

  1. Define a method in your theme so that drupal can give you more suggestions for form twig file.
function <theme_name>_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {
  if ($hook == 'form' & !empty($variables['element']['#id'])) {
          $suggestions[] = 'form__' . str_replace('-', '_', $variables['element']['#id']);
  }
}
  1. Enable twig debug from your services.yml You can see the name of twig files from where the output is coming and it also gives you the file suggestions names.

Now open your form page, and inspect or view its html. Near the form, you will see something like below:

Drupal twig debug

As we can see that the form twig is coming from core/themes/classy/templates/form/form.html.twig, and the suggestion twig file is form--node-article-form.html.twig

You can simply copy the form.html.twig file from classy folder and copy into your theme’s templates folder. I put it in templates/form/

Its content looks like:

{% raw %}
<form{{ attributes }}>
  {{ children }}
</form>
{% endraw %}

Note: With this, you can not reorder or theme individual fields. For this, see method-2.

Now, lets say we want to theme title field. In html, we can see its output is coming from core/themes/classy/templates/form/input.html.twig, and its suggestions are input--textfield.html.twig.

I’m using bootstrap theme. So, my modified twig file looks like:

{% raw %}
{%
  set classes = [
    'form-control rounded'
  ]
%}
<input{{ attributes.addClass(classes) }} />{{ children }}
{% endraw %}

Similarly for submit button, I copied template file input.html.twig to input--submit.html.twig, and its content looks like:

{% raw %}
{%
  set classes = [
    'btn btn-secondary mb-4 w-100 ml-0 mt-2'
  ]
%}
<input{{ attributes.addClass(classes) }} />{{ children }}
{% endraw %}

My final form twig file looks like:

{% raw %}
<div class="border-top border-bottom bg-white mt-4" id="lead">
  <div class="row">
    <div class="col-8 mx-auto">
      <form{{ attributes }}>
        {{ children }}
      </form>
    </div>
  </div>
</div>
{% endraw %}

Output

Drupal twig form

Method-2

In above method, you can theme form and its individual elements. But, you can not theme the ordering of form elements. Example: You want to show your form in two columns.

Lets take a look.

Goto your theme file: life2.theme (life2 is name of my theme)

function life2_theme($existing, $type, $theme, $path) {
  return array(
    'node_article_form' => array(
      'render element' => 'form',
      'template' => 'form/form--story-write-form',
    ),
  );
}

function life2_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if ($form_id === 'node_article_form') {
    $form['#theme'] = 'node_article_form';
  }
}

With above code, you can also specify your desired template filename. Lets see content of form--story-write-form

{% raw %}
<form{{ attributes }}>
  <div class="border-top border-bottom bg-white mt-4" id="lead">
    <div class="row">
      <div class="col-8 mx-auto">
        {{ form.title }}
        {{ form.body }}
        {{ form |without('title')|without('body')|without('field_tags')}}
      </div>
      <div class="col-4 mx-auto">
        {{ form.field_tags }}
      </div>
    </div>
  </div>
</form>
{% endraw %}

Output

Drupal themed Form output

You can ofcourse have more beautiful design.

I hope it helps.

Related Posts

Drupal 8 - How to create a Page with admin access and create its menu entry in Reports (No Coding)

Drupal 8 - How to create a Page with admin access and create its menu entry in Reports (No Coding)

Introduction I needed a report page, where I wanted to have some information…

Drupal: How to detect country and redirect to country specific website by using Cloudflare

Drupal: How to detect country and redirect to country specific website by using Cloudflare

Introduction Assume you have a drupal website and using cloudflare. You are…

Drupal - How to rename column of a content type

Drupal - How to rename column of a content type

Introduction You already have a content type with one or more fields in it…

Drupal 8 - How to hide help link About text formats and text format guidelines

Drupal 8 - How to hide help link About text formats and text format guidelines

Problem In drupal textarea field, it was always a pain to see the two links…

Drupal 8 Smart Image Style - Handle aspect ratio for small and long images

Drupal 8 Smart Image Style - Handle aspect ratio for small and long images

Problem Statement I’ve been using image styles, and heavily used “Scale and crop…

Drupal 8 Comment module - How to configure comments module from ugly to beautiful - Theming comments module

Drupal 8 Comment module - How to configure comments module from ugly to beautiful - Theming comments module

Introduction Drupal provides a powerful comment module, which comes as a part of…

Latest Posts

Software Security in the AI Era: How to Write Secure Code When AI Writes Code Too

Software Security in the AI Era: How to Write Secure Code When AI Writes Code Too

In 2025, 72% of professional developers used AI-assisted coding tools daily. By…

SQL Injection: The Complete Guide to Understanding, Preventing, and Detecting SQLi Attacks

SQL Injection: The Complete Guide to Understanding, Preventing, and Detecting SQLi Attacks

SQL injection has been on the OWASP Top 10 since the list was created in 200…

How to Be a Full-Time Freelancer: Resources, Finding Clients, and Building a Sustainable Business

How to Be a Full-Time Freelancer: Resources, Finding Clients, and Building a Sustainable Business

Making the leap from full-time employment to freelancing is one of the most…

Deep Dive on Elasticsearch: A System Design Interview Perspective

Deep Dive on Elasticsearch: A System Design Interview Perspective

“If you’re searching, filtering, or aggregating over large volumes of semi…

Deep Dive on Apache Kafka: A System Design Interview Perspective

Deep Dive on Apache Kafka: A System Design Interview Perspective

“Kafka is not a message queue. It’s a distributed commit log that happens to be…

Deep Dive on Redis: Architecture, Data Structures, and Production Usage

Deep Dive on Redis: Architecture, Data Structures, and Production Usage

“Redis is not just a cache. It’s a data structure server that happens to be…