Commit 63998484 authored by Dries's avatar Dries

Issue #2151439 by Wim Leers: Run node op links through #post_render_cache to...

Issue #2151439 by Wim Leers: Run node op links through #post_render_cache to prevent render caching granularity being
parent dd3e5a11
......@@ -6,13 +6,13 @@
*/
use Drupal\Core\Entity\EntityInterface;
use Drupal\node\NodeInterface;
use Drupal\node\NodeTypeInterface;
use Drupal\Core\Language\Language;
use Drupal\entity\Entity\EntityDisplay;
use Drupal\Core\Template\Attribute;
use Drupal\menu_link\Entity\MenuLink;
use Drupal\menu_link\MenuLinkStorageController;
use Drupal\node\NodeInterface;
/**
* Implements hook_help().
......@@ -121,45 +121,41 @@ function book_entity_info(&$entity_info) {
}
/**
* Adds relevant book links to the node's links.
*
* @param \Drupal\Core\Entity\EntityInterface $node
* The book page node to add links to.
* @param $view_mode
* The view mode of the node.
*/
function book_node_view_link(NodeInterface $node, $view_mode) {
$links = array();
$account = \Drupal::currentUser();
if (isset($node->book['depth'])) {
if ($view_mode == 'full' && node_is_page($node)) {
$child_type = \Drupal::config('book.settings')->get('child_type');
$access_controller = Drupal::entityManager()->getAccessController('node');
if (($account->hasPermission('add content to books') || $account->hasPermission('administer book outlines')) && $access_controller->createAccess($child_type) && $node->isPublished() && $node->book['depth'] < MENU_MAX_DEPTH) {
$links['book_add_child'] = array(
'title' => t('Add child page'),
'href' => 'node/add/' . $child_type,
'query' => array('parent' => $node->book['mlid']),
);
}
if ($account->hasPermission('access printer-friendly version')) {
$links['book_printer'] = array(
'title' => t('Printer-friendly version'),
'href' => 'book/export/html/' . $node->id(),
'attributes' => array('title' => t('Show a printer-friendly version of this book page and its sub-pages.'))
);
* Implements hook_node_links_alter().
*/
function book_node_links_alter(array &$node_links, NodeInterface $node, array &$context) {
if ($context['view_mode'] != 'rss') {
$account = \Drupal::currentUser();
if (isset($node->book['depth'])) {
if ($context['view_mode'] == 'full' && node_is_page($node)) {
$child_type = \Drupal::config('book.settings')->get('child_type');
$access_controller = \Drupal::entityManager()->getAccessController('node');
if (($account->hasPermission('add content to books') || $account->hasPermission('administer book outlines')) && $access_controller->createAccess($child_type) && $node->isPublished() && $node->book['depth'] < MENU_MAX_DEPTH) {
$links['book_add_child'] = array(
'title' => t('Add child page'),
'href' => 'node/add/' . $child_type,
'query' => array('parent' => $node->book['mlid']),
);
}
if ($account->hasPermission('access printer-friendly version')) {
$links['book_printer'] = array(
'title' => t('Printer-friendly version'),
'href' => 'book/export/html/' . $node->id(),
'attributes' => array('title' => t('Show a printer-friendly version of this book page and its sub-pages.'))
);
}
}
}
}
if (!empty($links)) {
$node->content['links']['book'] = array(
'#theme' => 'links__node__book',
'#links' => $links,
'#attributes' => array('class' => array('links', 'inline')),
);
if (!empty($links)) {
$node_links['book'] = array(
'#theme' => 'links__node__book',
'#links' => $links,
'#attributes' => array('class' => array('links', 'inline')),
);
}
}
}
......@@ -467,10 +463,6 @@ function book_node_view(EntityInterface $node, EntityDisplay $display, $view_mod
);
}
}
if ($view_mode != 'rss') {
book_node_view_link($node, $view_mode);
}
}
/**
......
......@@ -2,7 +2,7 @@
/**
* @file
* Contains \Drupal\node\Entity\NodeInterface.
* Contains \Drupal\node\NodeInterface.
*/
namespace Drupal\node;
......
......@@ -35,33 +35,14 @@ public function buildContent(array $entities, array $displays, $view_mode, $lang
$display = $displays[$bundle];
$entity->content['links'] = array(
'#theme' => 'links__node',
'#pre_render' => array('drupal_pre_render_links'),
'#attributes' => array('class' => array('links', 'inline')),
);
// 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.
$links = array();
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,
),
);
}
$entity->content['links']['node'] = array(
'#theme' => 'links__node__node',
'#links' => $links,
'#attributes' => array('class' => array('links', 'inline')),
'#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),
),
);
// Add Language field text element to node render array.
......@@ -77,6 +58,81 @@ public function buildContent(array $entities, array $displays, $view_mode, $lang
}
}
/**
* #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')),
);
}
/**
* {@inheritdoc}
*/
......
<?php
use Drupal\Core\Entity\EntityInterface;
use Drupal\node\Entity\NodeInterface;
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Xss;
......@@ -939,6 +940,37 @@ function hook_node_type_delete(\Drupal\node\NodeTypeInterface $type) {
drupal_set_message(t('You have just deleted a content type with the machine name %type.', array('%type' => $type->id())));
}
/**
* Alter the links of a node.
*
* @param array &$links
* A renderable array representing the node links.
* @param \Drupal\node\NodeInterface $entity
* The node being rendered.
* @param array &$context
* Various aspects of the context in which the node links are going to be
* displayed, with the following keys:
* - 'view_mode': the view mode in which the comment is being viewed
* - 'langcode': the language in which the comment is being viewed
*
* @see \Drupal\node\NodeViewBuilder::renderLinks()
* @see \Drupal\node\NodeViewBuilder::buildLinks()
*/
function hook_node_links_alter(array &$links, NodeInterface $entity, array &$context) {
$links['mymodule'] = array(
'#theme' => 'links__node__mymodule',
'#attributes' => array('class' => array('links', 'inline')),
'#links' => array(
'node-report' => array(
'title' => t('Report'),
'href' => "node/{$entity->id()}/report",
'html' => TRUE,
'query' => array('token' => \Drupal::getContainer()->get('csrf_token')->get("node/{$entity->id()}/report")),
),
),
);
}
/**
* @} End of "addtogroup hooks".
*/
......@@ -6,6 +6,7 @@
*/
use Drupal\Core\Entity\EntityInterface;
use Drupal\node\NodeInterface;
use Drupal\entity\Entity\EntityDisplay;
/**
......@@ -56,13 +57,18 @@ function statistics_node_view(EntityInterface $node, EntityDisplay $display, $vi
'type' => 'setting',
);
}
}
if ($view_mode != 'rss') {
/**
* Implements hook_node_links_alter().
*/
function statistics_node_links_alter(array &$node_links, NodeInterface $entity, array &$context) {
if ($context['view_mode'] != 'rss') {
if (\Drupal::currentUser()->hasPermission('view post access counter')) {
$statistics = statistics_get($node->id());
$statistics = statistics_get($entity->id());
if ($statistics) {
$links['statistics_counter']['title'] = format_plural($statistics['totalcount'], '1 view', '@count views');
$node->content['links']['statistics'] = array(
$node_links['statistics'] = array(
'#theme' => 'links__node__statistics',
'#links' => $links,
'#attributes' => array('class' => array('links', 'inline')),
......@@ -72,17 +78,6 @@ function statistics_node_view(EntityInterface $node, EntityDisplay $display, $vi
}
}
/**
* Implements hook_node_view_alter().
*/
function statistics_node_view_alter(&$build, EntityInterface $node, EntityDisplay $display) {
// If statistics were added to the node render array, we can't use the render
// cache.
if (isset($build['links']['statistics'])) {
unset($build['#cache']);
}
}
/**
* Implements hook_menu().
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment