Score:1

How do I re-order a node's body and link fields in my Bartik subtheme?

in flag

I have a simple subtheme of the standard Bartik theme in Drupal 9.3.0. By default, when a node is rendered, its links, eg. "read more", "log in", come before the body.

For example,

<div class="node__content clearfix">
  <div class="node__links">
    <ul class="links inline">
      <li class="node-readmore"><a href="/node/11" rel="tag" >Read more</a></li>
      <li class="comment-forbidden"><a href="/login?destination=/comment/reply/node/11/comment_node_story%23comment-form">Log in</a> to post comments</li>
    </ul>
  </div>
  <div class="clearfix text-formatted field field--name-body ...">
    <p>Body teaser ...</p>
  </div>
</div>

I want to swap the two components, ie. body and links, so that the body is rendered first and the links second. However, I can't determine which template to override to do this.

node.html.twig contains:

<div{{ content_attributes.addClass('node__content', 'clearfix') }}>
  {{ content }}
</div>

which suggests that {{ content }} consists of the links and body. However I can't figure out where its rendering takes place.

Can anyone point me in the right direction?

leymannx avatar
ne flag
Why don't you use the node type's display settings for that? There's a whole UI and numerous formatters to do what you want without needing to code anything. You can also use the Field Group module if you feel the need to add additional wrappers around any group of fields.
in flag
@leymannx I'm not sure why I went for a subtheme solution - possibly because I was subtheming anyway for a different issue. Anyway, I went and updated the custom display settings and dragged `links` below `body`, saved these settings, reverted my subtheme to use `{{ content }}`, cleared all my caches, refreshed the page and ... the `links` displayed _above_ the `body`. I'm not sure what I'm doing wrong, however I'm not getting the expected outcome. You're right though, this is the way to do it, ie. use the UI rather than code (if I could just get it to work).
in flag
I also tried using the Bartik theme, rather than my subtheme, and got the same result, ie. `links` then `body`.
leymannx avatar
ne flag
There's nothing wrong about sub-theming. Much easier to apply custom CSS/JS with your own sub-theme. It's just that with what you are doing in templates now, you defeat the UI, the display settings, which are there to do what you want with a couple of clicks.
leymannx avatar
ne flag
Doing this in `node.html.twig` applies for all node types. Copying `node.html.twig` to `node--my-type.html.twig`, flush cache and adjust this, applies only for the "My type" node type.
Score:2
ua flag
{{ content }}

contains everything, you can be more granular and replace it with, for example:

{{ content.title }} 
{{ content.body }}
{{ content.field_name }}
{{ content.links }}
Score:1
ne flag

Simply go to Structure > Content types > My content type > Manage display.

https://example.com/admin/structure/types/manage/page/display.

Screenshot of Drupal's Field UI

There you re-order fields displayed in your default frontend theme with a couple of clicks, export config, done. For deployment git push the exported config files, on prod git pull it again and now import config, done.

You can also use the Field Group module if you feel the need to add additional wrappers around any group of fields through the UI.

By templating all the things you defeat the Field UI while the display settings are always the first place where any future maintainer of that site will look why something looks odd or simply wants to change a formatter and then might wonder why it has no effect. "Damn, I need to look through the templates now and code the stuff that could have been changed with one click."

Only template when you really have the need to adjust the markup to more advanced needs like when working with web components or some fancy JS plugin for slideshows that has no Drupal module yet but requires certain markup nesting.

in flag
Thanks for the detailed answer. I had found the "manage display" configuration that you've highlighted. What I missed the first time around was the different tabs for "Default", "RSS" and "Teaser". D'oh! Once I re-ordered the fields across _all_ the tabs, the display matched what I needed.
leymannx avatar
ne flag
@dave – These "Default" etc. tabs represent **view modes**. When visiting a single term for example https://example.com/taxonomy/term/3 the term will be rendered in the "Default" (or sometimes called "Full") view mode. In other places (e.g. when you build a Views page listing taxonomy terms) they might get rendered in the "Teaser" view mode displaying only a subset of fields. Same applies for node types. On that page https://example.com/taxonomy/term/3 by default all nodes being tagged with this term are displayed in "Teaser" view mode displaying only the title and trimmed body of the nodes.
Score:0
pw flag

In your node template say "node--article.html.twig" you can reorder links and body as follow.

<div{{ content_attributes.addClass('content') }}>
{{ content.body }} 
{{ content.links }} 
you can also use {{ kint(content) }} in your template to view other things as follow.

enter image description here

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.