Chris@0: currentUser = $current_user ?: \Drupal::currentUser(); Chris@18: if (!$entity_repository) { Chris@18: @trigger_error('The entity.repository service must be passed to NodeViewController::__construct(), it is required before Drupal 9.0.0. See https://www.drupal.org/node/2549139.', E_USER_DEPRECATED); Chris@18: $entity_repository = \Drupal::service('entity.repository'); Chris@18: } Chris@18: $this->entityRepository = $entity_repository; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public static function create(ContainerInterface $container) { Chris@0: return new static( Chris@18: $container->get('entity_type.manager'), Chris@0: $container->get('renderer'), Chris@18: $container->get('current_user'), Chris@18: $container->get('entity.repository') Chris@0: ); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function view(EntityInterface $node, $view_mode = 'full', $langcode = NULL) { Chris@0: $build = parent::view($node, $view_mode, $langcode); Chris@0: Chris@0: foreach ($node->uriRelationships() as $rel) { Chris@18: $url = $node->toUrl($rel)->setAbsolute(TRUE); Chris@0: // Add link relationships if the user is authenticated or if the anonymous Chris@0: // user has access. Access checking must be done for anonymous users to Chris@0: // avoid traffic to inaccessible pages from web crawlers. For Chris@0: // authenticated users, showing the links in HTML head does not impact Chris@0: // user experience or security, since the routes are access checked when Chris@0: // visited and only visible via view source. This prevents doing Chris@0: // potentially expensive and hard to cache access checks on every request. Chris@0: // This means that the page will vary by user.permissions. We also rely on Chris@0: // the access checking fallback to ensure the correct cacheability Chris@0: // metadata if we have to check access. Chris@0: if ($this->currentUser->isAuthenticated() || $url->access($this->currentUser)) { Chris@0: // Set the node path as the canonical URL to prevent duplicate content. Chris@0: $build['#attached']['html_head_link'][] = [ Chris@0: [ Chris@0: 'rel' => $rel, Chris@0: 'href' => $url->toString(), Chris@0: ], Chris@0: TRUE, Chris@0: ]; Chris@0: } Chris@0: Chris@0: if ($rel == 'canonical') { Chris@0: // Set the non-aliased canonical path as a default shortlink. Chris@0: $build['#attached']['html_head_link'][] = [ Chris@0: [ Chris@0: 'rel' => 'shortlink', Chris@0: 'href' => $url->setOption('alias', TRUE)->toString(), Chris@0: ], Chris@0: TRUE, Chris@0: ]; Chris@0: } Chris@0: } Chris@0: Chris@18: // Since this generates absolute URLs, it can only be cached "per site". Chris@18: $build['#cache']['contexts'][] = 'url.site'; Chris@18: Chris@0: // Given this varies by $this->currentUser->isAuthenticated(), add a cache Chris@0: // context based on the anonymous role. Chris@0: $build['#cache']['contexts'][] = 'user.roles:anonymous'; Chris@0: Chris@0: return $build; Chris@0: } Chris@0: Chris@0: /** Chris@0: * The _title_callback for the page that renders a single node. Chris@0: * Chris@0: * @param \Drupal\Core\Entity\EntityInterface $node Chris@0: * The current node. Chris@0: * Chris@0: * @return string Chris@0: * The page title. Chris@0: */ Chris@0: public function title(EntityInterface $node) { Chris@18: return $this->entityRepository->getTranslationFromContext($node)->label(); Chris@0: } Chris@0: Chris@0: }