1

This is some code which we're using to merge together content types into the body of an article:

<?php

function remove_p($string) {
  $first_p=substr($string,0,3);
  if($first_p=="<p>") {
    $string=str_replace('<p>','',$string,$temp=1);
  }
  return $string;
}


function custom_press_release_node_view(array &$build, \Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode) {

  $node_array = $build['#node']->toArray();
  if ($node_array['type'][0]['target_id'] == 'press_release' || $node_array['type'][0]['target_id'] == 'article') {

    // Get the location entity ID
    $field_name = $entity->get('field_office_location')->getValue();

    $location_id = $field_name[0]['target_id'];

    // Get the location name
    $term_object = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($location_id);

    if(is_object($term_object)) {
      $term_array = $term_object->toArray();
    }

    // Generate output like - December 5, 2017
    $new_time_format = date('F d, Y', strtotime(substr($build['created'][0]['#markup'], 0, -7)));

    // Body text from Drupal
    $old_body = $build['body'][0]['#text'];

    $body = '<p><strong>';
    if (is_array($term_array)) {
      $body .= $term_array['name'][0]['value'] . ', ';
    }
    $body .= $new_time_format . ' – </strong>';
    $body .= remove_p($old_body) . '</p>';

    // Modified body text
    $build['body'][0]['#text'] = $body;

  }

}

I think that this would be better done in my theme file, but we weren't able to call the functions we needed within the theme.

Did we just miss something, or is this something that just needs to be done as a separate module?

2 Answers 2

2

What you missed is, that you can achieve all that output manipulation by just using the admin UI and view modes. It has the benefit of you being able to adjust the output order and available fields without having to touch any code. And gives you more power and flexibility to administer how content is displayed.

By incident, your solution matches a question answered just recently here: How to modify the value of a taxonomy field of a node using hook_node_view()?

Please have a look to my answer there, which describes how to show a field of the the taxonomy terms on the nodes by using the UI.

You can easily adjust the proceedings by e.g. creating a dedicated display mode for your content nodes instead and adding the required fields there.

Additionally, you like to show the formatted created time, which you can either preprocess within a theme's hook_preprocess_HOOK() (so for example yourtheme_preprocess_node()), but also have already exposed within the template variables as {{ date }} in your node.html.twig template.

3
  • Hey Mario. Thanks for your time here. There are so many facets of Drupal 8 Core. I keep finding stuff. You might be right about the being able to use the .twig file, but I also needed to modify the body to strip out the first html paragraph tag. I don't see how to do this using .twig or the admin UI. I haven't dug into display modes, so will continue poking around. Nice to see these docs drupal.org/docs/8/api/entity-api/… Dec 23, 2017 at 23:53
  • 1
    @MikeGifford: As you are manipulating the markup of the field, I'd always go for a theme hook to do the manipulation. This keeps a distinct line between functional code (core/modules) and theming, and thus enables you to replace the theme without having to alter program logic in a possible later stage of your application's life cycle. To strip out the first <p> tag, check out hook_preprocess_HOOK() for pre-processing variables that are passed to template files. This not only applies to the node entity, but can be used for field templates as well (and can be placed in your theme file). Dec 25, 2017 at 0:15
  • I looked at hook_preprocess_HOOK(), but either didn't find the variables I needed via dpm() or examples I could build on. Not sure which at this point. Thanks though. Dec 26, 2017 at 16:10
1

Hooks go in the .module file, to my knowledge, the only hooks that can also work in the .theme file are preprocess and alter hooks.

3
  • 2
    For the hook shown in the question is true, but in general it depends from the module invoking the hook. The Views module invokes hooks implemented by themes. It's safe to assume that themes are not involved with every type of hooks, though, since that happens most of the time. +1
    – apaderno
    Dec 23, 2017 at 7:11
  • I agree that most hooks belong to modules. Just as soon as modules return or manipulate HTML outside the scope of theme implementations and custom templates (that can be overridden or extended by a theme), text filters or hook_help(), I consider it something that should be changed. And the source from the original question does not contain anything that really requires hook_node_view() to manipulate the output. Just my humble opinion. Dec 23, 2017 at 10:12
  • 2
    @MarioSteinitz The question shows an implementation of hook_node_view() and then asks Did we just miss something, or is this something that just needs to be done as a separate module? It's hard to say that it can be done from the user interface, since the computation is a little involuted, but the question is about doing it from a module or a theme.
    – apaderno
    Dec 23, 2017 at 16:18

Your Answer

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

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