2

I have a hook_entity_view_alter() function inside the .module file for a custom content entity type that I am working on. I want to be able to conditionally show or hide fields in the canonical view of the entity based on the value of that field.

Example for a checkbox field: show it in the canonical if it was checked in the form, hide it in the canonical completely if it was unchecked in the form.

I am using unset($build['field_id']) for fields that are not inside field collections, and this is working fine. However, I would also like to use unset() for some fields that are contained within field collections.

I feel like this is probably a pretty simple thing to do and I'm just completely missing it. I've been var_dumping $build for a while and can't figure out what to unset, or if this is even the way to do it.

edit: here is the code I am working on in {module}.module

function {module}_{entity}_view_alter(array &$build, Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display) {

  $notAllowed = stripos($entity->get('field_category')->getValue()[0]['value'], "Not Allowed");
  $allowedConditionally = $entity->get('field_maintenance_info')->first()->getFieldCollectionItem()->get('field_allowed_on_maintenance')->getValue();

  if ($notAllowed !== false) {
    if (!$allowedConditionally[0]['value']) {
        //the next 4 lines work with fields defined at the module settings level, not inside field collections - this works!
        unset($build['field_allowed_1']);
        unset($build['field_there_are_multiple_varieti']);
        unset($build['field_variations']);
        $build['title']['#prefix'] = "No ";
    }
  }

  $protein = stripos($entity->get('field_category')->getValue()[0]['value'], "Protein");

  //this is just a loop I had for exploring $build, this outputs string(2) "25" which I am pretty sure is the field collection ID
  //'field_allowed_1' and 'field_serving_settings' are both field collections, the latter nested inside the former
  if (!($protein && !$notAllowed) && !($notAllowed && $protein2 && $allowedOnMaintenance)) {
    var_dump($build['field_allowed_1'][0]['#field_collection_item']->field_serving_settings[0]->value);
  }
}
6
  • Field collection uses it's own entity type field_collection_item. You can target this one to change the fields inside. If it still does not work, perhaps you can put some code in the question what you have done so far.
    – 4uk4
    Aug 4, 2016 at 20:12
  • @4k4 Thanks for the reply. I added my function to show what's going on.
    – saramm1
    Aug 4, 2016 at 20:20
  • what keys are in $build['field_allowed_1'][0] beside '#field_collection_item'?
    – 4uk4
    Aug 4, 2016 at 20:41
  • IMO you are better off using jQuery for this. As I am not sure if you can get instantaneous response using your current approach. Similarly to my answer to this other Q How to change a fields label name based on another fields value? PS: As I later learned, you can use hook_form_alter() to add the jquery to your content type nodes rather than modifying the Seven theme.
    – No Sssweat
    Aug 5, 2016 at 0:10
  • @4k4 the fields according to print_r are: #theme #field_collection_item #view_mode #cache #weight #pre_render
    – saramm1
    Aug 5, 2016 at 12:40

1 Answer 1

3

HOOK_entity_view_alter() works with render elements. That are all array keys, that have no '#' sign.

At the point you are now there are only fields prepared for rendering on the top level, that means the fields, which are not in a field collection.

Fields that are inside a field collection have at this point no renderable output.

To get the render elements of these fields you have to use the hook for field_collection_item:

function mymodule_field_collection_item_view_alter(&$build, $entity, $display) {
   kint($build);
}

Here you will be able to unset fields inside the field collection.

9
  • Thanks for the helpful information. I am trying this approach, but the function doesn't seem to be firing at all: function {module}_field_collection_item_view_alter(&$build, $entity, $display) { forEach ($build as $key => $val) print_r($key . " "); exit(1); } Also tried replacing "field_collection_item" in the function name with the machine name of one my field collections, that didn't do it either.
    – saramm1
    Aug 5, 2016 at 14:13
  • If you have a field collection item on your page it should fire. You can only use the entity type id, no field name. api.drupal.org/api/drupal/…
    – 4uk4
    Aug 5, 2016 at 14:52
  • weird, I still can't get it to fire -- this function is defined in my .module file outside/after my main hook_{entity}_view_alter, which I assume isn't an issue, hook_field_collection_item_view_alter isn't working for me. I tried hook_field_collection_view_alter too just in case, but nothing seems to be getting this code to fire, it's just loading the entity as normal with none of the print_r content or exit(1). Most of the documentation I can find on this is for drupal 7, does this feature still exist in drupal 8? (I don't see why it wouldn't, but this is weird...)
    – saramm1
    Aug 5, 2016 at 14:58
  • You can try mymodule_entity_view_alter(), this will catch the views of all entities. Use kint($build) and you will see the complete structure of your page. api.drupal.org/api/drupal/…
    – 4uk4
    Aug 5, 2016 at 15:03
  • Is there a stable version of kint for d8? I was looking earlier but only found a sandbox build -- is that one ok to use?
    – saramm1
    Aug 5, 2016 at 15:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.