Issue #2498849 by catch, dawehner: Entity view controller title rendering is expensive
parent
2f370af9c5
commit
4fb37aa1ff
|
@ -56,6 +56,31 @@ class EntityViewController implements ContainerInjectionInterface {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-render callback to build the page title.
|
||||
*
|
||||
* @param array $page
|
||||
* A page render array.
|
||||
*
|
||||
* @return array
|
||||
* The changed page render array.
|
||||
*/
|
||||
public function buildTitle(array $page) {
|
||||
$entity_type = $page['#entity_type'];
|
||||
$entity = $page['#' . $entity_type];
|
||||
// If the entity's label is rendered using a field formatter, set the
|
||||
// rendered title field formatter as the page title instead of the default
|
||||
// plain text title. This allows attributes set on the field to propagate
|
||||
// correctly (e.g. RDFa, in-place editing).
|
||||
if ($entity instanceof FieldableEntityInterface) {
|
||||
$label_field = $entity->getEntityType()->getKey('label');
|
||||
if (isset($page[$label_field])) {
|
||||
$page['#title'] = $this->renderer->render($page[$label_field]);
|
||||
}
|
||||
}
|
||||
return $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a page to render a single entity.
|
||||
*
|
||||
|
@ -78,22 +103,9 @@ class EntityViewController implements ContainerInjectionInterface {
|
|||
->getViewBuilder($_entity->getEntityTypeId())
|
||||
->view($_entity, $view_mode, $langcode);
|
||||
|
||||
// If the entity's label is rendered using a field formatter, set the
|
||||
// rendered title field formatter as the page title instead of the default
|
||||
// plain text title. This allows attributes set on the field to propagate
|
||||
// correctly (e.g. RDFa, in-place editing).
|
||||
if ($_entity instanceof FieldableEntityInterface) {
|
||||
$label_field = $_entity->getEntityType()->getKey('label');
|
||||
if ($label_field && $_entity->getFieldDefinition($label_field)->getDisplayOptions('view')) {
|
||||
// We must render the label field, because rendering the entity may be
|
||||
// a cache hit, in which case we can't extract the rendered label field
|
||||
// from the $page renderable array.
|
||||
$build = $this->entityManager->getTranslationFromContext($_entity)
|
||||
->get($label_field)
|
||||
->view($view_mode);
|
||||
$page['#title'] = $this->renderer->render($build);
|
||||
}
|
||||
}
|
||||
$page['#pre_render'][] = [$this, 'buildTitle'];
|
||||
$page['#entity_type'] = $_entity->getEntityTypeId();
|
||||
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
|
|
@ -21,15 +21,12 @@ class NodePreviewController extends EntityViewController {
|
|||
*/
|
||||
public function view(EntityInterface $node_preview, $view_mode_id = 'full', $langcode = NULL) {
|
||||
$node_preview->preview_view_mode = $view_mode_id;
|
||||
$build = array('nodes' => parent::view($node_preview, $view_mode_id));
|
||||
$build = parent::view($node_preview, $view_mode_id);
|
||||
|
||||
$build['#attached']['library'][] = 'node/drupal.node.preview';
|
||||
|
||||
$build['#title'] = $build['nodes']['#title'];
|
||||
unset($build['nodes']['#title']);
|
||||
|
||||
// Don't render cache previews.
|
||||
unset($build['nodes']['#cache']);
|
||||
unset($build['#cache']);
|
||||
|
||||
foreach ($node_preview->uriRelationships() as $rel) {
|
||||
// Set the node path as the canonical URL to prevent duplicate content.
|
||||
|
|
|
@ -20,10 +20,7 @@ class NodeViewController extends EntityViewController {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function view(EntityInterface $node, $view_mode = 'full', $langcode = NULL) {
|
||||
$build = array('nodes' => parent::view($node));
|
||||
|
||||
$build['#title'] = $build['nodes']['#title'];
|
||||
unset($build['nodes']['#title']);
|
||||
$build = parent::view($node);
|
||||
|
||||
foreach ($node->uriRelationships() as $rel) {
|
||||
// Set the node path as the canonical URL to prevent duplicate content.
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Entity\Controller\EntityViewControllerTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Entity\Controller;
|
||||
|
||||
use Drupal\Core\Entity\Controller\EntityViewController;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Entity\Controller\EntityViewController
|
||||
* @group Entity
|
||||
*/
|
||||
class EntityViewControllerTest extends UnitTestCase{
|
||||
|
||||
/**
|
||||
* Tests the enhancer method.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\Controller\EntityViewController::view()
|
||||
*/
|
||||
public function testView() {
|
||||
|
||||
// Mock a view builder.
|
||||
$render_controller = $this->getMockBuilder('Drupal\entity_test\EntityTestViewBuilder')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$render_controller->expects($this->any())
|
||||
->method('view')
|
||||
->will($this->returnValue('Output from rendering the entity'));
|
||||
|
||||
// Mock an entity manager.
|
||||
$entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
|
||||
$entity_manager->expects($this->any())
|
||||
->method('getViewBuilder')
|
||||
->will($this->returnValue($render_controller));
|
||||
|
||||
// Mock the 'entity_test' entity type.
|
||||
$entity_type = $this->getMockBuilder('Drupal\Core\Entity\ContentEntityType')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$entity_type->expects($this->once())
|
||||
->method('getKey')
|
||||
->with('label')
|
||||
->will($this->returnValue('name'));
|
||||
|
||||
// Mock the 'name' field's definition.
|
||||
$field_definition = $this->getMock('Drupal\Core\Field\BaseFieldDefinition');
|
||||
$field_definition->expects($this->any())
|
||||
->method('getDisplayOptions')
|
||||
->with('view')
|
||||
->will($this->returnValue(NULL));
|
||||
|
||||
// Mock an 'entity_test' entity.
|
||||
$entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$entity->expects($this->once())
|
||||
->method('getEntityType')
|
||||
->will($this->returnValue($entity_type));
|
||||
$entity->expects($this->any())
|
||||
->method('getFieldDefinition')
|
||||
->with('name')
|
||||
->will($this->returnValue($field_definition));
|
||||
|
||||
|
||||
// Initialize the controller to test.
|
||||
$controller = new EntityViewController($entity_manager, $this->getMock('Drupal\Core\Render\RendererInterface'));
|
||||
|
||||
// Test the view method.
|
||||
$this->assertEquals($controller->view($entity, 'full'), 'Output from rendering the entity');
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue