1

I'm on D10.2.x. My site uses Gin as back-end theme but also as fallback front-end, being decoupled and having to "front-end page" actually shown via Drupal.

I'd want to override the default node add\edit form for some extra html markup. As I can't just override via a *.twig template in the theme folder, I'm trying with a module.

I've tried wit the code\example from e.g. How do I theme a custom form? or https://makedrupaleasy.com/articles/drupal-10-how-render-any-form-twig-template

My code is the following:

my_module.module:

/**
 * Implements hook_theme().
 */
function my_module_theme($existing, $type, $theme, $path) {
  return [
    'my_custom_form_twig' => [
      'variables' => [],
      'render element' => 'form',
    ],
  ];
}

/**
 * Implements hook_form_alter().
 */
function my_module_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  //removed temporarily the check on $form_id
  $form['#theme'][] = 'my_custom_form_twig';
}

/templates/my-custom-form-twig.html.twig

{{ dd() }}
<h1>MY CUSTOM TWIG</h1>
<form{{ attributes }}>
  {{ children }}
</form>

dump result

 array:13 [▼
  "form" => []
  "theme_hook_original" => "my_custom_form_twig"
  "attributes" => Drupal\Core\Template\Attribute {#1517 ▶}
  "title_attributes" => Drupal\Core\Template\Attribute {#1738 ▶}
  "content_attributes" => Drupal\Core\Template\Attribute {#1515 ▶}
  "title_prefix" => []
  "title_suffix" => []
  "db_is_active" => true
  "is_admin" => true
  "logged_in" => true
  "user" => Drupal\Core\Session\AccountProxy {#1404 ▶}
  "directory" => "themes/contrib/gin"
  "theme_hook_suggestions" => []
]

However this doesn't work, as I'm facing two issues:

  1. As a test, I've checked that the override works for most forms on the site, as they are replaced with my custom twig. However, the node edit\add forms still use the original one, so I suppose some extra logic is done by the Node module and I need to do something more to override it, but I don't know\can't find what.
  2. As shown by the dump of my twig (in the other places of site), the form array is actually empty. There is also no element or children object so I can't rely on them as fallback. Therefore my twig can't actually print the form.

Thank you for suggestion on either of the two problems.

EDIT:

The answer by @No Sssweat solved the issue.


/**
 * Implements hook_theme().
 */
function my_module_alfresco_theme($existing, $type, $theme, $path) {
  return [
    'node_edit_form__custom_template' => [
      'render element' => 'form',
      'base hook' => 'node_edit_form',
    ],
  ];
}

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function my_module_theme_suggestions_node_edit_form_alter(array &$suggestions, array &$variables) {
  $suggestions[] = 'node_edit_form__custom_template';
}

Please note it's important that:

New suggestions must begin with the value of HOOK, followed by two underscores to be discoverable.

as explained by the API

otherwise, the suggestion will work (at least in my case), but with a warning.

-- INVALID FILE NAME SUGGESTIONS: my_custom_template

And eventually use the mark-up of the admin theme used, e.g. in my case web/themes/contrib/gin/templates/node/node-edit-form.html.twig

2
  • Maybe try drupal.org/project/formdazzle. It also gives you [form-id].html.twig.
    – leymannx
    Commented May 8 at 7:47
  • @leymannx: thanks for the suggestion. I've used that module on other sites, but I don't think it would solve my issue in this one, as I don't "have" a front-end theme where simply put the twig files without overriding it with some sort of extra-code.
    – Giuseppe
    Commented May 14 at 13:45

1 Answer 1

2

Good try, the proper way:

/**
 * Implements hook_theme().
 */
function mymodule_theme($existing, $type, $theme, $path) {
  return [
    'my_custom_template' => [
      'render element' => 'form',
      'base hook' => 'node_edit_form',
    ],
  ];
}

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function mymodule_theme_suggestions_node_edit_form_alter(array &$suggestions, array $variables) {
  $suggestions[] = 'node_edit_form__custom_template';
}

In case you wonder where the 'render element' => 'form', came from. I copied/got it from the "form" theme hook definition.


mymodule/templates/node-edit-form--custom-template.html.twig

<h1>MY CUSTOM TWIG</h1>
{{ form  | without('field_image') }}
4
  • Hi, thanks.The twig now load. Unfortunately this solution doesn't seem what I'd need: the children element is a Markup string, so it's not possible to work with it. There's an element array but for some reasons it doesn't work like other renderable array. E.g. {{ element | without('field_image') }} still print all the form with also the field_image. I hoped to find a form array, like usual. Do you any idea\other suggestions? Thanks
    – Giuseppe
    Commented May 6 at 15:33
  • 1
    @Giuseppe well if you add your {{ dd() }} dump to the web/core/modules/system/templates/form.html.twig you're going to get the exact same thing. Plus if you look at the code comments, the only available variables for this template file are attributes and children. Thus, if you're seeking to use form then this ain't the template file. Doing a search where form is being used, grep -r "{{ form }}" The one that makes most sense is web/core/modules/node/templates/node-edit-form.html.twig. (see updated answer)
    – No Sssweat
    Commented May 8 at 7:27
  • See updated answer @Giuseppe
    – No Sssweat
    Commented May 8 at 8:08
  • 1
    thanks, the updated answer was almost the right way (or at least one, of the way) to implement a custom twig template! I had to change my_custom_template to node_edit_form__custom_template to be compliant to the API and avoid a warning. Please see the updated question after the EDIT and eventually update your answer - as I marked accepted.
    – Giuseppe
    Commented May 14 at 13:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.