devel_wizard-2.x-dev/templates/spell/entity_type/content/view_controller.php.twig
templates/spell/entity_type/content/view_controller.php.twig
{%
include '@devel_wizard/php/devel_wizard.php.file.header.php.twig'
with {
'namespace': content.namespace,
}
%}
use {{ content.interface_fqn }};
{%-
include '@devel_wizard/php/devel_wizard.php.file.use_statements.php.twig'
with {
'useStatements': {
'Drupal\\Component\\Utility\\Xss': '',
'Drupal\\Core\\Entity\\Controller\\EntityViewController': '',
'Drupal\\Core\\Entity\\EntityHandlerInterface': '',
'Drupal\\Core\\Entity\\EntityInterface': '',
'Drupal\\Core\\Entity\\EntityTypeInterface': '',
'Drupal\\Core\\Entity\\EntityTypeManagerInterface': '',
'Drupal\\Core\\Render\\RendererInterface': '',
'Drupal\\Core\\Session\\AccountInterface': '',
'Symfony\\Component\\DependencyInjection\\ContainerInterface': '',
},
}
%}
class ViewController extends EntityViewController implements EntityHandlerInterface {
protected AccountInterface $currentUser;
/**
* {@inheritdoc}
*/
public static function createInstance(
ContainerInterface $container,
EntityTypeInterface $entity_type,
) {
return static::create($container);
}
/**
* {@inheritdoc}
*
* @return static
*/
public static function create(ContainerInterface $container) {
// @phpstan-ignore-next-lines
return new static(
$container->get('entity_type.manager'),
$container->get('renderer'),
$container->get('current_user'),
);
}
/**
* {@inheritdoc}
*/
public function __construct(
EntityTypeManagerInterface $entityTypeManager,
RendererInterface $renderer,
AccountInterface $currentUser,
) {
$this->currentUser = $currentUser;
parent::__construct($entityTypeManager, $renderer);
}
/**
* Route title callback.
*
* @phpstan-return array<string, mixed>
*/
public function title({{ content.interface }} ${{ content.id }}): array {
return [
'#markup' => ${{ content.id }}->label(),
'#allowed_tags' => Xss::getHtmlTagList(),
];
}
/**
* {@inheritdoc}
*
* @param \{{ content.interface_fqn }} $_entity
* @param string $view_mode
* @param null|string $langcode
*
* @phpstan-return array<string, mixed>
*
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
public function view(EntityInterface $_entity, $view_mode = 'full', $langcode = NULL) {
$build = parent::view($_entity, $view_mode);
foreach ($_entity->uriRelationships() as $rel) {
$url = $_entity->toUrl($rel);
// Add link relationships if the user is authenticated or if the anonymous
// user has access. Access checking must be done for anonymous users to
// avoid traffic to inaccessible pages from web crawlers. For
// authenticated users, showing the links in HTML head does not impact
// user experience or security, since the routes are access checked when
// visited and only visible via view source. This prevents doing
// potentially expensive and hard to cache access checks on every request.
// This means that the page will vary by user.permissions. We also rely on
// the access checking fallback to ensure the correct cacheability
// metadata if we have to check access.
if ($this->currentUser->isAuthenticated() || $url->access($this->currentUser)) {
// Set the path as the canonical URL to prevent duplicate content.
$build['#attached']['html_head_link'][] = [
[
'rel' => $rel,
'href' => $url->toString(),
],
TRUE,
];
}
if ($rel === 'canonical') {
// Set the non-aliased canonical path as a default shortlink.
$build['#attached']['html_head_link'][] = [
[
'rel' => 'shortlink',
'href' => $url->setOption('alias', TRUE)->toString(),
],
TRUE,
];
}
}
// Given this varies by $this->currentUser->isAuthenticated(), add a cache
// context based on the anonymous role.
$build['#cache']['contexts'][] = 'user.roles:anonymous';
return $build;
}
}
