.../Entity/Controller/EntityViewController.php | 15 +++++- .../lib/Drupal/node/Controller/NodeController.php | 48 ----------------- .../Drupal/node/Controller/NodeViewController.php | 56 ++++++++++++++++++++ core/modules/node/node.routing.yml | 2 +- .../Entity/Controller/EntityViewControllerTest.php | 24 +++++++++ 5 files changed, 95 insertions(+), 50 deletions(-) diff --git a/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php b/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php index aac92bc..81aa6af 100644 --- a/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php +++ b/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php @@ -9,6 +9,7 @@ use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -61,9 +62,21 @@ public static function create(ContainerInterface $container) { * A render array as expected by drupal_render(). */ public function view(EntityInterface $_entity, $view_mode = 'full', $langcode = NULL) { - return $this->entityManager + $page = $this->entityManager ->getViewBuilder($_entity->getEntityTypeId()) ->view($_entity, $view_mode, $langcode); + + // If the entity's label is rendered using a field formatter, set that as + // the page title instead, so that attributes set on the field propagate + // correctly (e.g. RDFa, in-place editing). + if ($_entity instanceof ContentEntityInterface) { + $label_field = $_entity->getEntityType()->getKey('label'); + if ($label_field && $_entity->getFieldDefinition($label_field)->getDisplayOptions('view')) { + $page['#title'] = drupal_render($page[$label_field], TRUE); + } + } + + return $page; } } diff --git a/core/modules/node/lib/Drupal/node/Controller/NodeController.php b/core/modules/node/lib/Drupal/node/Controller/NodeController.php index b16b93d..c448b7b 100644 --- a/core/modules/node/lib/Drupal/node/Controller/NodeController.php +++ b/core/modules/node/lib/Drupal/node/Controller/NodeController.php @@ -117,41 +117,6 @@ public function revisionOverview(NodeInterface $node) { } /** - * Displays a node. - * - * @param \Drupal\node\NodeInterface $node - * The node we are displaying. - * - * @return array - * An array suitable for drupal_render(). - */ - public function page(NodeInterface $node) { - $build = $this->buildPage($node); - - foreach ($node->uriRelationships() as $rel) { - // Set the node path as the canonical URL to prevent duplicate content. - $build['#attached']['drupal_add_html_head_link'][] = array( - array( - 'rel' => $rel, - 'href' => $node->url($rel), - ) - , TRUE); - - if ($rel == 'canonical') { - // Set the non-aliased canonical path as a default shortlink. - $build['#attached']['drupal_add_html_head_link'][] = array( - array( - 'rel' => 'shortlink', - 'href' => $node->url($rel, array('alias' => TRUE)), - ) - , TRUE); - } - } - - return $build; - } - - /** * The _title_callback for the node.view route. * * @param NodeInterface $node @@ -165,19 +130,6 @@ public function pageTitle(NodeInterface $node) { } /** - * Builds a node page render array. - * - * @param \Drupal\node\NodeInterface $node - * The node we are displaying. - * - * @return array - * An array suitable for drupal_render(). - */ - protected function buildPage(NodeInterface $node) { - return array('nodes' => $this->entityManager()->getViewBuilder('node')->view($node)); - } - - /** * The _title_callback for the node.add route. * * @param \Drupal\node\NodeTypeInterface $node_type diff --git a/core/modules/node/lib/Drupal/node/Controller/NodeViewController.php b/core/modules/node/lib/Drupal/node/Controller/NodeViewController.php new file mode 100644 index 0000000..d2ff07e --- /dev/null +++ b/core/modules/node/lib/Drupal/node/Controller/NodeViewController.php @@ -0,0 +1,56 @@ + parent::view($node)); + + $build['#title'] = $build['nodes']['#title']; + unset($build['nodes']['#title']); + + foreach ($node->uriRelationships() as $rel) { + // Set the node path as the canonical URL to prevent duplicate content. + $build['#attached']['drupal_add_html_head_link'][] = array( + array( + 'rel' => $rel, + 'href' => $node->url($rel), + ) + , TRUE); + + if ($rel == 'canonical') { + // Set the non-aliased canonical path as a default shortlink. + $build['#attached']['drupal_add_html_head_link'][] = array( + array( + 'rel' => 'shortlink', + 'href' => $node->url($rel, array('alias' => TRUE)), + ) + , TRUE); + } + } + + return $build; + } + +} diff --git a/core/modules/node/node.routing.yml b/core/modules/node/node.routing.yml index 617b16a..8e66a47 100644 --- a/core/modules/node/node.routing.yml +++ b/core/modules/node/node.routing.yml @@ -47,7 +47,7 @@ node.add: node.view: path: '/node/{node}' defaults: - _content: '\Drupal\node\Controller\NodeController::page' + _content: '\Drupal\node\Controller\NodeViewController::view' _title_callback: '\Drupal\node\Controller\NodeController::pageTitle' requirements: _entity_access: 'node.view' diff --git a/core/tests/Drupal/Tests/Core/Entity/Controller/EntityViewControllerTest.php b/core/tests/Drupal/Tests/Core/Entity/Controller/EntityViewControllerTest.php index 0bc6353..ac6c886 100644 --- a/core/tests/Drupal/Tests/Core/Entity/Controller/EntityViewControllerTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/Controller/EntityViewControllerTest.php @@ -49,10 +49,34 @@ public function testView() { ->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\FieldDefinition'); + $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);