To improve the editing experience for content creators, you often want to alter the styling for the form that is used to create and edit nodes. These forms use the node-edit-form.html.twig
template to generate the HTML when using an administration theme, and no extra theme suggestions are provided by Drupal natively. So, when you provide a custom version of this Twig template, it is used for each content type in your site.
But what if you want, e.g., node-edit-form--article.html.twig
to be used to provide custom HTML when creating/editing nodes of the type article (i.e., machine name). Luckily, you can add extra theme hook suggestions by implementing hook_theme_suggestions_HOOK_alter();
this function can be placed in a custom module or theme. In the example below we assume we have a custom module named example and want to add suggestions for the original node_edit_form
theme hook (which is provided by node_theme()
) based on the type of content being created/edited:
/**
* Implements hook_theme_suggestions_HOOK_alter() for node_edit_form.
*/
function example_theme_suggestions_node_edit_form_alter(array &$suggestions, array $variables) {
$route_match = \Drupal::routeMatch();
if ($node = $route_match->getParameter('node')) {
// When editing an existing node, add the node's bundle as the theme hook
// suggestion.
$suggestions[] = $variables['theme_hook_original'] . '__' . $node->bundle();
}
elseif ($node_type = $route_match->getParameter('node_type')) {
// When a new node is created, the node type (object) is provided.
$suggestions[] = $variables['theme_hook_original'] . '__' . $node_type->id();
}
return $suggestions;
}
From the currently active route match object, the node type object (NodeTypeInterface
) can be obtained when creating a node or the node (NodeInterface
) itself when it is being edited. Both parameters are upcasted (converted) automatically to actual objects and make it easy to add theme hook suggestions based on the content type. These theme hook suggestions allow for targeted preprocess functions and/or Twig files to be found and used by Drupal to render the forms. Now, when for instance node-edit-form--article.html.twig
file is placed in the expected location (i.e., the templates folder of our custom example module), this template is used to generate HTML for the forms used to create and edit nodes of the type article (i.e., machine name). Note that underscore (_) characters in theme hooks (suggestions) should be replaced by hyphens (-) in Twig file names.
Usually, the node edit form is delivered by the administration theme, and it can be overkill to provide a custom administration theme, just for overwriting the styling of a few node types. Therefore, you can also provide the custom Twig templates from a custom module. For these templates to be found by Drupal, you have to register the theme hook suggestion in the module providing the Twig template:
/**
* Implements hook_theme().
*/
function example_theme() {
return [
// Register the theme hook suggestion, which allows to provide custom Twig
// template for the node create/edit form a module.
'node_edit_form__<node_type>' => [
'render element' => 'form',
'base hook' => 'node_edit_form',
],
];
}
It's recommended to set the 'base hook'
property, which ensures the base hook's files are included, and it's preprocess functions are invoked.
Note that Drupal's core administration themes change the theme function when creating/editing nodes, using:
/**
* Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\NodeForm.
*/
function administration_theme_form_node_form_alter(&$form, FormStateInterface $form_state) {
$form['#theme'] = ['node_edit_form'];
}
So, in case you want users can create/edit nodes using your main theme, don't forget to implement similar behavior; otherwise, the node_edit_form
theme hook isn't used.
Comments