NodeViewBuilder.php 4.43 KB
Newer Older
1 2 3 4
<?php

/**
 * @file
5
 * Definition of Drupal\node\NodeViewBuilder.
6 7 8 9 10
 */

namespace Drupal\node;

use Drupal\Core\Entity\EntityInterface;
11
use Drupal\Core\Entity\EntityViewBuilder;
12
use Drupal\entity\Entity\EntityDisplay;
13 14 15 16

/**
 * Render controller for nodes.
 */
17
class NodeViewBuilder extends EntityViewBuilder {
18 19

  /**
20
   * {@inheritdoc}
21
   */
22
  public function buildContent(array $entities, array $displays, $view_mode, $langcode = NULL) {
23 24 25 26
    $return = array();
    if (empty($entities)) {
      return $return;
    }
27 28 29 30

    // Attach user account.
    user_attach_accounts($entities);

31
    parent::buildContent($entities, $displays, $view_mode, $langcode);
32

33
    foreach ($entities as $entity) {
34 35
      $bundle = $entity->bundle();
      $display = $displays[$bundle];
36 37

      $entity->content['links'] = array(
38 39 40 41 42 43 44 45
        '#type' => 'render_cache_placeholder',
        '#callback' => '\Drupal\node\NodeViewBuilder::renderLinks',
        '#context' => array(
          'node_entity_id' => $entity->id(),
          'view_mode' => $view_mode,
          'langcode' => $langcode,
          'in_preview' => !empty($entity->in_preview),
        ),
46 47 48
      );

      // Add Language field text element to node render array.
49 50
      if ($display->getComponent('langcode')) {
        $entity->content['langcode'] = array(
51 52 53 54 55 56 57
          '#type' => 'item',
          '#title' => t('Language'),
          '#markup' => language_name($langcode),
          '#prefix' => '<div id="field-language-display">',
          '#suffix' => '</div>'
        );
      }
58 59 60
    }
  }

61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
  /**
   * #post_render_cache callback; replaces the placeholder with node links.
   *
   * Renders the links on a node.
   *
   * @param array $context
   *   An array with the following keys:
   *   - node_entity_id: a node entity ID
   *   - view_mode: the view mode in which the node entity is being viewed
   *   - langcode: in which language the node entity is being viewed
   *   - in_preview: whether the node is currently being previewed
   *
   * @return array
   *   A renderable array representing the node links.
   */
  public static function renderLinks(array $context) {
    $links = array(
      '#theme' => 'links__node',
      '#pre_render' => array('drupal_pre_render_links'),
      '#attributes' => array('class' => array('links', 'inline')),
    );

    if (!$context['in_preview']) {
      $entity = entity_load('node', $context['node_entity_id']);
      $links['node'] = self::buildLinks($entity, $context['view_mode']);

      // Allow other modules to alter the node links.
      $hook_context = array(
        'view_mode' => $context['view_mode'],
        'langcode' => $context['langcode'],
      );
      \Drupal::moduleHandler()->alter('node_links', $links, $entity, $hook_context);
    }

    return $links;
  }

  /**
   * Build the default links (Read more) for a node.
   *
   * @param \Drupal\node\NodeInterface $entity
   *   The node object.
   * @param string $view_mode
   *   A view mode identifier.
   *
   * @return array
   *   An array that can be processed by drupal_pre_render_links().
   */
  protected static function buildLinks(NodeInterface $entity, $view_mode) {
    $links = array();

    // Always display a read more link on teasers because we have no way
    // to know when a teaser view is different than a full view.
    if ($view_mode == 'teaser') {
      $node_title_stripped = strip_tags($entity->label());
      $links['node-readmore'] = array(
        'title' => t('Read more<span class="visually-hidden"> about @title</span>', array(
          '@title' => $node_title_stripped,
        )),
        'href' => 'node/' . $entity->id(),
        'html' => TRUE,
        'attributes' => array(
          'rel' => 'tag',
          'title' => $node_title_stripped,
        ),
      );
    }

    return array(
      '#theme' => 'links__node__node',
      '#links' => $links,
      '#attributes' => array('class' => array('links', 'inline')),
    );
  }

136
  /**
137
   * {@inheritdoc}
138
   */
139 140
  protected function alterBuild(array &$build, EntityInterface $entity, EntityDisplay $display, $view_mode, $langcode = NULL) {
    parent::alterBuild($build, $entity, $display, $view_mode, $langcode);
141
    if ($entity->id()) {
142 143 144
      $build['#contextual_links']['node'] = array(
        'route_parameters' =>array('node' => $entity->id()),
      );
145
    }
146 147 148

    // The node 'submitted' info is not rendered in a standard way (renderable
    // array) so we have to add a cache tag manually.
149
    $build['#cache']['tags']['user'][] = $entity->getAuthorId();
150 151 152
  }

}