How to create custom node template file in Drupal 8 and 9 themes
Here we are going to discuss how we are going to over right node template from our custom theme.
Here we are going to customize content pages say a node of an article content.
Assuming you have a custom theme which extends a base theme.
In my case I have a bootstrap theme as base theme and I am extending it with custom theme
Download below bootstrap base theme
https://www.drupal.org/project/bootstrap
So for creating a custom theme by extending this base theme , you can see sample bootstrap theme in downloaded bootstrap theme.
Folder \starterkits contains a THEMENAME folder, which you can copy and place it in your custom themes folder.
Rename THEMENAME with your custom theme name.
So my custom theme template folder is empty. We are going to create templates files here.
First enable twig debug in local settings.
See this article for enabling twig debug.
Here I have added a content in Article content type.
Open article page.
Right click and click inspect in chrome browser.
Here you can see multiple node template suggestion.
Also you can see possible templates in below path in classy theme
\core\themes\classy\templates\
Here we are customizing templates of article content type.
You can see the name node—article–full.html.twig
Next copy node.html.twig from bootstrap theme templates folder(\themes\contrib\bootstrap\templates\node\node.html.twig) and place it in your custom theme templates folder and rename to node—article–full.html.twig
Clear the cache and load the newly added article page. This article will be rendered through node—article—full.html.twig that we placed in our custom theme.
You can confirm this by placing a class name in a div in above template file.
I have placed below div in node—article–full.html.twig file. Clear the cache. You can see this div in rendered article page.
<div class=”image-div”>
</div>
Next we are going to extract each fields in the node and give a wrapper div.
For printing variables and its contents, you can use kint or functions in Devel module.
Here in my Drupal 9 website I enabled Devel module and in Devel settings enabled Symfony var-dumper option.
If I use below function in template
{{ dpm()}}
We can see all variable and its values.
You can see field_image and body files inside content array.
So inside your article node template file remove {{ content }}
Wrap your fields inside div tags as below.
<div class="img-class"> {{ content['field_image'] }} </div> <div class="body-class"> {{ content['body'] }} </div>
Clear the cache and reload the article page. You can see image and body wrapped inside div tags as below.
Below provided possible node fields templates
<!– FILE NAME SUGGESTIONS:
* field–node–field-image–article.html.twig
* field–node–field-image.html.twig
* field–node–article.html.twig
* field–field-image.html.twig
* field–image.html.twig
x field.html.twig
–>
If you need to change mark up then only go for creating above templates. Else go for .theme hooks.
Adding class to img tag
You can use preprocess_image hook in .theme file.
function YOURTHEME_preprocess_image(&$variables) { // Check the image style. if ($variables['style_name'] == 'MYSTYLE') { // Set class. $variables['attributes']['class'][] = 'img-customstyle'; } }
Adding class to other fields
you can use YOURTHEME_preprocess_field preprocess function.
function YOURTHEME_preprocess_field(&$variables) { if ($variables['element']['#field_name'] == 'fielda_name') { // Set class. $variables['attributes']['class'][] = 'style-class'; } }
Altering image fields in node
You can control img tag of the rendered image by changing display format of image. Here got to structure and edit article content type. You can see manage display as below. Change format to URL to image.
Flesh the cache and you will get image as link text in template. So in field template field–node–field-image–article.html.twig
{% for item in items %} <div class="image-article">{{ item.content }}</div> {% endfor %}
item.content content is a url to the image.
In your .theme file you can use a variable value with base url as below.
function YOURTHEME_preprocess(&$variables) { $host = \Drupal::request()->getHost(); $variables['base_path'] = $host; }
SO in your twig file you can use s below to get full URL to
File- path\templates\node\field–node–field-image–article.html.twig
{% for item in items %} <div class="image-article">{{ base_path }}{{item.content }}</div> {% endfor %}