Chris@0: currentUser = $current_user ?: \Drupal::currentUser(); 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@0: $container->get('entity.manager'), Chris@0: $container->get('renderer'), Chris@0: $container->get('current_user') 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@0: $url = $node->toUrl($rel); 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@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@0: return $this->entityManager->getTranslationFromContext($node)->label(); Chris@0: } Chris@0: Chris@0: }