Skip to content

Instantly share code, notes, and snippets.

@drubb
Last active February 6, 2024 08:46
Show Gist options
  • Save drubb/9d76110480675435fb5c7b164b100303 to your computer and use it in GitHub Desktop.
Save drubb/9d76110480675435fb5c7b164b100303 to your computer and use it in GitHub Desktop.
Custom Twig extension to provide links to an entity edit form. Permissions are checked, the current page is added as destination, and the link is styled using a fontawesome icon in this example. Usage in Twig: {{ eel(node) }}, {{ eel(user) }} or similar.
<?php declare(strict_types=1);
namespace Drupal\my_module;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Path\CurrentPathStack;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
/**
* Twig extension to provide a link to the edit form of a content entity,
* using the current page as destination. The link is only added if the
* current user has the necessary permissions. It's rendered as an icon.
*/
final class EntityEditLinkTwigExtension extends AbstractExtension {
use StringTranslationTrait;
/**
* Constructs the extension object.
*/
public function __construct(
private readonly AccountProxyInterface $currentUser,
private readonly CurrentPathStack $currentPath,
) {
}
/**
* {@inheritdoc}
*/
public function getFunctions(): array {
return [
new TwigFunction('eel', [$this, 'createEditLink']),
];
}
/**
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
public function createEditLink(ContentEntityInterface $entity): array {
// We'll return a render array, as we need to add cache metadata.
$build = [];
// Cached links will vary by user permissions.
$build['#cache']['contexts'] = ['user.permissions'];
// Cache must be invalidated when the user is updated, e.g. when roles change.
$build['#cache']['tags'] = ['user:' . $this->currentUser->id()];
// If the current user isn't allowed to edit the entity, we're done.
if (!$entity->access('update')) {
return $build;
}
// Build the url for the edit form, with the current page as destination.
$url = $entity->toUrl('edit-form')
->setOption('query', [
'destination' => $this->currentPath->getPath(),
]);
// Add the link to the render array and return it.
$build['content'] = [
'#type' => 'link',
'#title' => [
'#type' => 'html_tag',
'#tag' => 'i',
'#value' => '',
'#attributes' => [
'class' => ['fa-solid', 'fa-pen'],
],
],
'#url' => $url,
'#attributes' => [
'title' => $this->t('Edit'),
],
];
return $build;
}
}
services:
mymodule.twig_extension:
class: Drupal\mymodule\EntityEditLinkTwigExtension
arguments: ['@current_user', '@path.current']
tags:
- { name: twig.extension }
<article>
<h2><a href="{{ url }}">{{ label }}</a>{{ eel(node) }}</h2>
{{ content }}
</article>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment