Problem/Motivation
The location of the entity in the $build array passed to hook_entity_view_alter isn't consistent between invocations, this means that implementing modules can not be sure where to look for the entity. For example:
$build['#comment'] = $entity (comment)
$build['#node'] = $entity (node)
$build['#account'] = $entity (user)
$build['#term'] = $entity (taxonomy_term)
Proposed resolution
Add an additional value in the $build array that declares the key in the array where the entity is located. This is called: #build_name and it's value is the key of the $build array where the entity can be found.
This is to minimise API change and provide a valid backport route for D7.
Remaining tasks
This approach needs to be reviewed really, and tests written.
User interface changes
None.
API changes
We'd be adding a new key/value to the $build array passed to hook_entity_view_alter, so that's an API change of sorts (an addition).
Original report by BTMash
I couldn't find an issue that seems to mark what I am finding so I posted a new issue. I was recently working with trying to get views (using the eva module) to display on the taxonomy term page. However, because taxonomy does not actually invoke hook_entity_view() (to note, only nodes, users, comments have such an implementation) but does allow for hook_entity_view_alter(), I went about to build out an implementation using that. However, I am finding that the build array when passed it has a different variable name for each of the entities that get passed in (and they are all different from the type. So:
$build['#comment'] = $entity (comment)
$build['#node'] = $entity (node)
$build['#account'] = $entity (user)
$build['#term'] = $entity (taxonomy_term)
So if someone wanted to try and build a generic module to tackle altering the view on an entity, they would need to put in if/else checks to get the entity appropriately. I think the simplest solution would be for all of these cases to set $build['#entity']. Its clear for various modules to understand, and module developers know what to look for in such situations. The other way is that anything that implements entities should invoke hook_entity_view() (along with hook_entity_view_alter().
| Comment | File | Size | Author |
|---|---|---|---|
| #42 | drupal-1170198-42.patch | 8.81 KB | tim.plunkett |
| #41 | drupal-1170198-41.patch | 8.54 KB | tim.plunkett |
| #39 | drupal-1170198-39.patch | 7.57 KB | tim.plunkett |
| #37 | drupal-1170198-37.patch | 7.58 KB | tim.plunkett |
| #33 | interdiff.txt | 2.79 KB | bas.hr |
Comments
Comment #1
joachim commentedCouldn't you just say:
$build['#' . $entity->type] ?
Comment #2
chx commented$build['#'. $entity_type] sounds sane to me. Whether we want $build['#entity'] is a matter to discuss. Can't see a harm in it but then you need #entity_type in there as well.
Comment #3
btmash commentedAgree. $build['#'. $entity_type] is fine as well (although I don't think $build['#entity_type'] is necessary given that the alter, entity_view, etc all pass through the type of entity as an argument for the hooks). So long as a module has an easy way to figure out which build variable is the entity.
Comment #4
catchComment #5
btmash commentedI never ended up getting back on this issue. So would the first step to try and get this into core be to add this to the various types of entities currently in core? Just so I remember to tackle them correctly (I don't miss out on any by mistake), would they be:
Comment #6
joachim commentedIs File an entity in core?
Comment #7
btmash commentedYou're right. File is also an entity in core (see it in the system module file) though does it have any functions where it goes through build a build mode?
Comment #8
catchThis sounds good but we should consider going straight to having view() etc. methods in the entity system which do this and applying those to the individual entities compared to cleaning up each individual pipeline for consistency - I'm personally fine whichever way we do that.
Comment #9
btmash commentedIn all honesty...I am *way* more in favor of your approach (view / build() methods as part of the entity system) than what I have asked for in my issue (though this will likely come into play as a part of it)) as I do think the individual entities having their own view methods (and each one, barring the taxonomy but would be with #1067120: Missing hook_taxonomy_term_view() or hook_entity_view() when viewing a term, pretty much being copy/paste jobs of each other) is inefficient usage of development time and more importantly can lead to (and has lead to) inconsistent behavior. I have been afraid of creating an issue on that one (a few folk have mentioned that this might be a 8.x thing only which leads to 'what happens for D7?') but am happy to help out with whichever path we end up on.
Comment #10
catchGeneric entity rendering is definitely an 8.x thing only.
Adding standard #build keys on top of the existing ones for D7 might be backportable, depends how an intrusive a change it might be.
Comment #11
btmash commentedFrom what chx said, $build['#'. $entity_type] is one possible approach. Another can be $build['#entity_type'] = (name of variable holding the entity build like 'term' or 'account' or 'node'). Seems a bit silly to grab the name of the variable that way though.
Comment #12
pjbarry21 commentedSubscribe
Comment #13
btmash commentedTo start things off and hopefully see it go somewhere better, I added a '#build_name' to each of the core entities that have a drupal_alter happening. Since there are only 4 entities that bring this out in core (atleast I hope it is only these), they have the build name added in. And it seems like it could be backportable to D7 in this scenario.
Comment #14
xjm#13 looks like a simple, backportable fix to me. Patch looks good to me, for what it's worth.
I wonder if we could do something similar to standardize entities in FAPI? (E.g. see #1261310: uid is not available in hook_field_attach_validate() and #1220212: Provide original entity in hook_field_attach_validate()).
Comment #15
xjmOne thought; would we maybe just want to use the full name of the key? E.g.:
'#build_name' => '#node',It's worth noting that in the user case it is called
#accountrather than#user, which is why this specific approach seems more viable than just referencing$build['#' . $entity->type].Comment #16
btmash commentedOk, updated the patch to have the # in there. And what you have said is precisely the reason. user gets account and taxonomy_term gets term which is why it has to go in this route until entity building gets standardized.
Comment #17
btmash commentedForgot to attach the actual patch...
Comment #18
btmash commentedNeeds to get rerolled.
Comment #19
xjmDid someone say "reroll"?
Comment #20
btmash commented#19: entity_build_variable_name-1170198-19.patch queued for re-testing.
Comment #22
xjmApparently someone still needs to say "reroll."
Comment #23
kim.pepperComment #24
kim.pepperRe-rolled
Comment #25
Zgear commentedrenamed to .patch ^^
Comment #26
xjmThanks for the reroll! That looks good.
If we want to add this property, we should probably add automated tests that use it (or at least assert that it is available).
Comment #27
steven jones commentedGoing to have a look at this.
Comment #28
steven jones commentedSo...here's a patch that adds some tests, I'm fairly certain that the tests are broken, sorry.
I've tried to keep the tests near the code that we're actually testing, but added the hook that allows us to test in a bit of a random place, so that would need cleaning up too.
Comment #30
bas.hr commentedI'm rewriting the patch
Comment #31
bas.hr commentedTests are fixed
Comment #32
tim.plunkettbas.hr, you should upload the test without that suffix so we actually see the failures. If you upload the test as the first patch and the combined as the second, the bot will leave it as needs review.
The do-not-test thing is for D7 patches on a D8 issue, for example.
Also an interdiff would have been good to have here.
Comment #33
bas.hr commentedOK thanks for pointing that out. I'm attaching the interdiff too.
Comment #35
tim.plunkettIt won't do that if you upload the tests patch first. This looks pretty good, are there going to be any docs about the new #build_mode part?
Comment #36
xjmThanks @bas.hr! Those tests look sufficient to me. It looks like there's coverage for comments, nodes, terms, and users; vocabularies and files do not have view modes in core currently (right?).
I agree with @tim.plunkett that we should also add documentation for the new property.
Additionally, there are a few minor cleanups we can make to the patch in the next reroll:
Let's improve these docs. (They're a bit ambiguous, the user test case is mislabeled, and "taxonomy" is misspelled.) I think for both the class summary and the
getInfo()description we can simply say:Tests hook_entity_view_alter() for insert_entity_name_here.For these, let's say:
Tests that the #build_name is set correctly for insert_entity_name_here.I think we can leave off the assertion messages for these. (It will then say, e.g.
hook_entity_view_alter:build_name:#comment found, which is fairly self-explanatory).We need a newline at the end of the file here.
Thanks everyone!
Comment #37
tim.plunkettThis is a straight port since node, comment, and user tests went PSR-0. I'll address the concerns from #35-36 in the next patch.
Comment #39
tim.plunkettWhoops, extra closing brace
Comment #41
tim.plunkettLeft out the setUp hunk by mistake. I think we're good now, but I'll wait one more time before actually improving the patch.
Comment #42
tim.plunkettWell, this is immensely useless now in D8, since each view_alter function now gets the entire entity as a second parameter: #1618136: Remove $type from entity hooks
But, rerolled nonetheless. I addressed all of the feedback from #36, except that part about documenting the #build_mode, since I don't know how to explain a useless addition. This should likely just go into D7, but leaving here for now.
Comment #43
tim.plunkettComment #44
tim.plunkettStill applies.
Comment #44.0
tim.plunkettUpdated issue summary.
Comment #45
berdir42: drupal-1170198-42.patch queued for re-testing.
Comment #47
btmash commentedLooking at D8 and the new hook_entity_view_alter, *seems* like this would be useless (unless the view is still based off what is in the build array). I'll take a look and see how things look for alterations sometime this week.
Comment #48
fabianx commentedThis is really nice, back to 7.x for now as it is fixed superior in D8.
Note even implementing that for core would leave contrib authors like entity module to update the build key first, which would probably happen sometime ...