I'm trying to get the field_group module to work with entities that do not use "content" as the property name of the renderable entity content. The module already uses a special case for user profiles. I specifically want it to work with Commerce product variation entities, but a generic solution is the goal. Examples:

$entity->content
$entity->user_profile
$entity->product_variation

Is there a standard method or technique to determine the name of the entity property that contains its renderable content?

Comments

Jaypan’s picture

Not by default, as entities don't aren't even guaranteed to have content (for example users don't really have a content field). But you can implement hook_entity_alter, and add your own key (ex content_field) and explicitly declare the field for each content type there. Then use the getDefinitions() method of the entity manager any time you need to know what the content key is.

John Pitcairn’s picture

Users don't have "content" as such, but there is a user_profile property that contains the fields that are rendered.

So how does the build/render process know that is the property to render? Is it the responsibility of the entity itself and that implementation is hidden?

I guess any module like field_group that wants to modify this is then stuck with special-casing for every entity that is fieldable but doesn't consider itself a "content" entity.

Seems like a good candidate for core entity enhancement if so, though it would be an API change.

Jaypan’s picture

So how does the build/render process know that is the property to render?

I'm afraid I don't understand the question. Entities render any fields that are attached to them that are either set to be displayed (on the manage display tab for the entity settings), or if there are no rules they are rendered by default.

The build process doesn't know that any single field is meant to be rendered or not, it's determined at build time by looking at the #access property of each element of the render array.

John Pitcairn’s picture

I'm not concerned with individual field rendering. For node entities, the renderable stuff will be inside $node->content, for example. I'm trying to figure out how the render process knows that $node->content is where the render arrays should be. Or $entity->user_profile for user entities. How is that actually defined?

Because to make field_group work generically, it would need to know that.

John Pitcairn’s picture

Perhaps I mean the build process, before rendering. How does that know where to put the render arrays?

Jaypan’s picture

Ok, I finally get what you're asking. However, I did a little testing, and I could not find $node->content nor $user->profile in Drupal 8. Where are you seeing these so that I can do some testing?

John Pitcairn’s picture

Actually, it's $variables['content'] and $variables['user_profile'], etc, when rendering an entity. Apologies. Are those keys effectively hard-coded or are they defined somewhere that is accessible to other modules?

I'm probably going to wind up working around it in hook_entity_view_alter to fix my own specific situation, but if it turns out there is a way to identify the appropriate key I will look at providing a patch to field_group module.

Jaypan’s picture

In what function are you seeing those values?

John Pitcairn’s picture

Um, hold on, investigating. I don't think field_group is doing what I think it is doing.

John Pitcairn’s picture

Thanks @Jaypan and apologies for the noise.

I now have a functional workaround for my specific use-case involving hook_preprocess_commerce_product_variation() and hook_field_group_build_pre_render_alter().

But the way field_group hard-codes the content element variables is not very contrib-friendly, the workaround could be a lot simpler, and I'll post an issue and proposed patch there I think.