TransWikia.com

Form in custom module using Controller: The HTML tag form isn't present in Twig

Drupal Answers Asked by Bohus Ulrych on December 8, 2021

I’m trying to render limited user edit form on custom page using Drupal Controller.
In the routing.yml I defined _controller, I do not want to use _form.

I want to display on the form e.g. only timezone field, but not the rest. And I’m not able to achieve it. I can render this field, other fields like form_build_id, form_id, form_token
But form html tag is not rendered at all.
It works only if I display the whole form with {{ form.form }}.

This is the content of the files I am using.

my_module.info.yml

name: 'My module'
type: module
description: 'my module'
core_version_requirement: ^8.8 || ^9

my_module.routing.yml

my_module.mymodule_controller_view::
  path: '/my-module'
  defaults:
    _controller: 'Drupalmy_moduleControllerMymoduleController::view'
    _title: 'My module'
  requirements:
    _permission: 'access content'

my_module.module

function my_module_theme($existing, $type, $theme, $path)
{
    $templates = array(
        'my_module_form' => [
            'render element' => 'form',
        ],
    );

    return $templates;
}

MymoduleController.php

namespace Drupalmy_moduleController;

use DrupalCoreControllerControllerBase;
use DrupaluserEntityUser;

class MymoduleController extends ControllerBase
{

    public function view()
    {
        $data['header'] = [
            '#type' => 'markup',
            '#markup' => '<h1>HEADER</h1>',
        ];

        $user = User::load(Drupal::currentUser()->id());
        $formObject = Drupal::entityTypeManager()
            ->getFormObject('user', 'default')
            ->setEntity($user);

        $form = Drupal::formBuilder()->getForm($formObject);

        $data['form'] = [
            '#theme' => 'my_module_form',
            'form' => $form,
        ];

        $data['footer'] = [
            '#type' => 'markup',
            '#markup' => '<h3>footer</h3>',
        ];

        return $data;
    }
}

my-module-form.html.twig

<div>TWIG TEMPLATE</div>

{{ form.form.timezone }}
{{ form.form.form_build_id }}
{{ form.form.form_token }}
{{ form.form.form_id }}
{{ form.form.actions }}

One Answer

This is not working, you can't use a form template in a controller. You have to assign the template to $form['#theme'] when building the form or in a form alter hook. Then it gets used by formBuilder()->getForm() automatically.

See for example seven_form_node_form_alter():

$form['#theme'] = ['node_edit_form'];

and the corresponding twig file for a two column layout:

core/themes/seven/templates/node-edit-form.html.twig

{#
/**
 * @file
 * Theme override for a node edit form.
 *
 * Two column template for the node add/edit form.
 *
 * This template will be used when a node edit form specifies 'node_edit_form'
 * as its #theme callback.  Otherwise, by default, node add/edit forms will be
 * themed by form.html.twig.
 *
 * Available variables:
 * - form: The node add/edit form.
 *
 * @see seven_form_node_form_alter()
 */
#}
<div class="layout-node-form clearfix">
  <div class="layout-region layout-region-node-main">
    {{ form|without('advanced', 'footer', 'actions') }}
  </div>
  <div class="layout-region layout-region-node-secondary">
    {{ form.advanced }}
  </div>
  <div class="layout-region layout-region-node-footer">
    <div class="layout-region-node-footer__content">
      {{ form.footer }}
      {{ form.actions }}
    </div>
  </div>
</div>

Form modes

A different approach would be to configure a form mode in UI containing only the field you want and then use it in your controller:

    $formObject = Drupal::entityTypeManager()
        ->getFormObject('user', 'custom_form_mode')
        ->setEntity($user);

See How do I load a form with a specific form display (form mode)?

Answered by 4k4 on December 8, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP