Problem/Motivation

Let's make a field template and access some date from the entity:

datetime = element['#object'].getCreatedTime|format_date('html_datetime')

That's less than ideal.

Proposed resolution

Provide at least entity by adding it in template_preprocess_field

$variables['entity'] = $element['#object'];

Remaining tasks

User interface changes

API changes

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner created an issue. See original summary.

dawehner’s picture

Issue tags: +Novice
dawehner’s picture

Issue summary: View changes
Jacine’s picture

This would be nice.

A little consistency in the variables available goes a very long way for us. This is especially true because debugging in templates right now is a nightmare, so every little improvement helps.

morsok’s picture

Status: Active » Needs review
FileSize
607 bytes

Yeah I think that help ease the pain for themers.

Here's a patch.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

joelpittet’s picture

Status: Needs review » Reviewed & tested by the community

This seems to be a nice idea to give access to the template for other fields.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

Let's add tests for this then.

kikoalonsob’s picture

Here is a more complete patch which alter some field templates too.

How can I add a test for this patch now? It will be my first test so...help is welcome!

OwilliwO’s picture

Don't forget to mark the issue as «needs review» to process tests.

OwilliwO’s picture

Status: Needs work » Needs review
Ashley George’s picture

On my local 8.3.x, I have applied the patch in #9.

In a field.html.twig, I included 'dump(entity)'.

Output of the object was printed to the screen, when viewing a node with fields.

I conclude this is working correctly.

Ashley George’s picture

Status: Needs review » Reviewed & tested by the community
alexpott’s picture

Status: Reviewed & tested by the community » Needs work

We still should have a test for this.

kikoalonsob’s picture

How can I test that a variable is available in a template?

joelpittet’s picture

@kikoalonsob, you can create or mock an node and print it's label with {{ entity.label }} in a field template as a possible test and assert the node title is displayed in that field. There are a bunch of examples of this in the existing tests to copy from.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

nesta_’s picture

Issue tags: +DevDaysSeville

add tag DevDaysSeville

mmbk’s picture

With a little help of @webflo : implemented a test for this function

mmbk’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 19: test_accessing_the_original-2761525-19.patch, failed testing. View results

mmbk’s picture

Status: Needs work » Needs review
FileSize
12.59 KB
dawehner’s picture

Issue summary: View changes

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

joelpittet’s picture

Status: Needs review » Needs work
Issue tags: -Needs tests +Vienna2017

Still applies, seems reasonable to want access to the entity, has tests. I'd RTBC it but there are a few comments needed on the other field templates.

To help find them use these:

find . -name field--*.html.twig
find . -name field.html.twig
derheap’s picture

Assigned: Unassigned » derheap
derheap’s picture

I used the find commands and checked the field templates.

Only 2 have no comments:

./core/modules/big_pipe/tests/themes/big_pipe_test_theme/templates/field--comment.html.twig -- Test only
./core/themes/classy/templates/field/field--text.html.twig -- extends field.html.twig

Test does not need a comment.
The other templates extends the original field.html.twig, so also no comment is needed.

The others are ok:

./core/modules/comment/templates/field--comment.html.twig -- ok
./core/modules/node/templates/field--node--created.html.twig -- ok
./core/modules/node/templates/field--node--title.html.twig -- ok
./core/modules/node/templates/field--node--uid.html.twig -- ok
./core/themes/bartik/templates/field--node--field-tags.html.twig -- ok
./core/themes/classy/templates/field/field--comment.html.twig -- ok
./core/themes/classy/templates/field/field--node--created.html.twig -- ok
./core/themes/classy/templates/field/field--node--title.html.twig -- ok
./core/themes/classy/templates/field/field--node--uid.html.twig -- ok
./core/themes/classy/templates/field/field--text-long.html.twig -- extends field--text.html.twig
./core/themes/classy/templates/field/field--text-with-summary.html.twig -- extends field--text.html.twig 
./core/themes/stable/templates/field/field--comment.html.twig -- ok
./core/themes/stable/templates/field/field--node--created.html.twig -- ok
./core/themes/stable/templates/field/field--node--title.html.twig -- ok
./core/themes/stable/templates/field/field--node--uid.html.twig -- ok

./core/modules/system/templates/field.html.twig -- ok
./core/modules/system/tests/themes/test_theme/templates/field.html.twig  -- ok
./core/themes/classy/templates/field/field.html.twig -- ok
./core/themes/stable/templates/field/field.html.twig -- ok 
derheap’s picture

Status: Needs work » Reviewed & tested by the community

There are no additional comments necessary.
I talked about it with joelpittet, he agreed to RTBC is. So I put it do RTBC.

derheap’s picture

Assigned: derheap » Unassigned
joelpittet’s picture

Thanks for double checking field--text.html.twig, I didn't realize they were extending.

Wim Leers’s picture

I see why it can be valuable in some cases. But at the same time, this moves us further away from having simple templates with just the data it needs injected. This patch explicitly adds the ability to easily get data not from the current level, but from the parent level.

If we decide we want this, ok, but we should be conscious about that.

dawehner’s picture

Well, in general I believe there will be always some tradeoff between real life usecases and simpleness. If field templates want the full entity they should be able in the theoretical future where they can specify their data dependencies. In that case do we really loose anything, by adding support already?

Wim Leers’s picture

I agree with you. In the current state of things, this probably makes sense. I just want us to realize there are indirect consequences too, that is all.

catch’s picture

Tagging for a front-end committer to review.

xjm’s picture

Hmm. I kind of feel like accessing the original entity in field templates should be hard, to avoid having business logic in templates?

Edit: I guess this is what #31 is getting at also.

But I'm kind of -1 to this change also.

dawehner’s picture

Can I ask the question where business logic actually belongs?

  • Preprocess? We argued a lot that moving things out of preprocess is the way to go
  • The entity templates? If they contain the business logic they can't determine how to render anything, because the fields are rendered already
  • The field templates are supposed to just render the field and by that not have business logic?
  • Put every logic into field templates?

I think this all comes down to the fact that entity/field templates aren't the actual right level of rendering. You want to build components to render stuff and just somehow pass along data to your domain specific component templates. For me at least, if field templates are the place you need to call out to those component templates, using the entity might be needed in that place.

Jacine’s picture

It seems like these discussion always come back to ease of access to context, which is very important in practice, but is sometimes discounted or overlooked in these discussions. I think the business logic argument is misapplied here. There is *always* going to be a need to derive context and act/theme/style accordingly. If we want to remove the process layer, which is a stated goal in #2702061: Unify & simplify render & theme system: component-based rendering (enables pattern library, style guides, interface previews, client-side re-rendering), I think we need to accept that context is needed, and make it a priority when considering changes.

Here are some real examples of where accessing the parent/child entity has been needed (not all are for fields but the general idea is the same):

  1. Nested Entities Galore

    We're dealing with more entity references than ever before, which makes theming harder. What you want to change may require going through 4-6 layers of templates. This is why people are fond of modules like Twig Field Value. Most people don't want to go through all that just to print a field value, and you can't really blame them. Kint and friends are not helpful here, so unless you are very patient and willing to sit there taking shots in the dark for hours (like me), you need to know the magic methods to get anything useful, in a debugger. Most people are sane, and just bypass this all completely, because it's VERY time consuming. And if you question the 4-6 levels of templates, let me give an example of one I'm working on as we speak:

    1. node.html.twig
    2. field--node--field-hero.html.twig or field--entity-reference-revisions.html.twig
      1. paragraph--hero.html.twig
      2. field--paragraph--field-video--hero.html.twig
      3. media--youtube.html.twig*
      4. field--media--field-video-url--youtube.html.twig*
      5. container--video-embed-iframe--youtube.html.twig**
      6. video-embed-iframe--youtube.html.twig*

      *These suggestions need to be customized, they're not specific enough. The Hero context needs to be explicit. Why? Because in the Hero context the video autoplays like a background image via the YouTube API, and in other places, it just needs to be a standard video embed.

      **This suggestion has already been customized. However, no other information is available to the the container, so I cannot complete this task without devoting more trial and error time to it, or without backend help. Sigh.

    3. Context of Parent entity, or Field value on Parent Entity

      In the same Hero component (paragraph entity), the design calls for using the parent node title in some cases (specifically, the articles vs landing pages). Paragraphs provides access to the parent entity, so the code was simply:

      {% set parent = paragraph.getParentEntity %}
      {{ parent.label }}
      
    4. Different Component Templates/Attributes/etc based on Parent/Child

      Back to the hero again, some have video media entities attached, others have images. In this case, you nay need to access the parent and the child entities to achieve designs. For example, if the child entity is a video media entity it might need different classes, and/or component template than an image.

    5. Wrapping a Field in a Link to the Parent

      Sometimes you just need to wrap an entity reference field in a link to parent entity, INSIDE the field wrapper, not outside. You might say this is the job for a formatter, but I disagree. Formatters only further increase the business logic in templates, because as the template author you've no control over what data structure might be sent to the template, due to options in the UI. They also come with complex caching challenges. A great example of potentially different data structures is a date field. It can be a timestamp, themed via #time, or just #markup. Fatal errors for trying to manipulate what is expected to be a timestamp, but isn't because someone changed the formatter is always fun.

    6. Providing a proper HTML structure

      Given a field_heading on a Paragraph entity, need to find the depth to give an accurate HTML/outline heading level, e.g.

      1. Parent is a node, the tag should probably be an H2.
      2. Parent is a paragraph, tag should probably be an H3.
      3. Parent is another field, the tag should probably be an H4, etc

    Bingo!

    I think this all comes down to the fact that entity/field templates aren't the actual right level of rendering. You want to build components to render stuff and just somehow pass along data to your domain specific component templates. For me at least, if field templates are the place you need to call out to those component templates, using the entity might be needed in that place.

    Exactly. I think most people would rather not get down to field templates for theming. We have a responsibility as coders to at least attempt to make our code as simple and readable as possible, but spreading everything out across soooo many templates, is counter to that goal. However, it's not escapable, so for me, it really depends on what kind of field it is. When I can, I do try to do as much as possibly globally for fields, e.g. field--field-type.html.twig. That way when I'm working in a parent entity, I can just print, or send it off to a component template as is, because that's easy to read/maintain, etc. However, that doesn't always make sense, and when I do need to get into a field template, I'd agree that accessing parent entity needs to be possible/easy. My point in mentioning this is the Context drives all of this, and context is often really hard. We should try to make it easier instead of harder. Saying this isn't needed to someone working with Drupal templates is sort of like saying you should not be able to have different labels and field settings for a given field that is shared across bundles of the same entity to a backend developer.


    This ended up being a much longer reply than I anticipated, and I assure you the tone of it is not snarky or anything. I'm just trying to provide some insight into the day-to-day challenges in hopes that we can all just accept that we need context AND business logic, and factor that into the solutions being developed.

    And Ultimately, I think the Paragraphs solution, of being able to use getParentEntity() is the best one, so if we can do something like that, it'd probably be better.

xjm’s picture

Thanks @Jacine, all that context (pun!) is really helpful for understanding this issue.

Jacine’s picture

Sure! I'm really glad it's helpful... :o)

star-szr’s picture

Stopping in to weigh in as one of the frontend framework managers:

IMO lack of context is (still) one of the biggest pain points in Drupal theming and something that people run into almost daily. I'm in favour of this change. At a glance, the patch looks reasonable and straightforward but I can't review or test it thoroughly at the moment.

Special thanks to @Jacine for the write up in #37.

Sidenote: I can't find the issue, but at one point during the D8 cycle theme system maintainers had discussed adding a separate $context alongside $variables so that stuff like this could be referenced in preprocess/templates to know where the hell you are in the nesting dolls.

xjm’s picture

@Cottser, @effulgentsia, and I discussed this issue today and came up with a couple recommendations:

  1. @Cottser previously proposed adding #2511548: Add a "context" array variable to all theme hooks and "#context" array property to all elements to provide optional contextual data. That's still open, but cites a past issue #2495419: Move the 'search-results' class from the render array and into a Classy template where it was added for providing metadata to a template for search. So let's do something like that here as well, by adding the entity to a context array in the variables. Using that pattern will help themers distinguish between information that's part of the current template, and information about what context the template is in to theme it based on that context.
  2. core/modules/node/templates/node.html.twig has some detailed documentation explaining what is and isn't available to do with the node entity there. We should provide similar docs in the field template about the field entity.
  3. We should probably also expand the tests that, to assert that you can't do the forbidden code-execution-type things that we indicate we restrict in the node template.

The patch is failing on a test that was broken in HEAD recently; it looks like it's not getting retested. But since we're updating the patch anyway that is fine.

Thanks everyone for working on this, and for explaining why it's needed.

xjm credited effulgentsia.

xjm’s picture

Adding credit.

xjm’s picture

Other reviewer credits.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

phpsubbarao’s picture

{{ element['#object'].getCreatedTime | date('F j, Y') }}
Worked for me.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.