Support for revisions in Twig functions

Created on 11 June 2025, 23 days ago

Problem/Motivation

The current versions of the module don't support loading entities by revision IDs.
Because of that, it is not possible to use drupal_entity, drupal_entity_form, drupal_field, drupal_image functions for anything but latest entity revision.

One of the possible use cases is displaying Paragraphs in a node template.

Steps to reproduce

1. Create a node with Paragraphs.
2. Create a node template displaying the Paragraph field with drupal_field.
3. Create a draft revision of the node, and edit the displayed Paragraph field.
4. Preview the node draft.

: the page displays Paragraph field from the draft node revision.
: the page displays latest published Paragraph field.

Proposed resolution

Implement new versions of drupal_entity, drupal_entity_form, drupal_field, drupal_image functions supporting loading entities by revision ID instead of entity ID.

Below is an example of the Twig function we implemented as a workaround:

/**
   * {@inheritdoc}
   */
  public function getFunctions(): array {
    // This function mimics the behavior of `drupal_field()` from the
    // Twig Tweak module, but it allows you to specify a revision ID instead
    // of the entity ID which is useful e.g. for Paragraphs.
    $functions[] = new TwigFunction(
      'drupal_field_revision',
      static function (
        string $field_name,
        string $entity_type,
        string $revision_id,
        $view_mode = 'full',
        string $langcode = NULL,
        bool $check_access = TRUE,
      ): array {
        // This part is different from the original `drupal_field()` function.
        // We are loading the entity by the revision ID instead of the entity
        // ID.
        $entityStorage = \Drupal::entityTypeManager()->getStorage($entity_type);
        /** @var \Drupal\Core\Entity\RevisionableStorageInterface $entityStorage */
        if (!$entityStorage instanceof RevisionableStorageInterface) {
          throw new \InvalidArgumentException(sprintf(
            'The entity type "%s" does not support revisions.',
            $entity_type,
          ));
        }

        $entity = $entityStorage->loadRevision($revision_id);
        // This is the original code part.
        if ($entity) {
          return \Drupal::service('twig_tweak.field_view_builder')
            ->build($entity, $field_name, $view_mode, $langcode, $check_access);
        }
        return [];
      },
    );
    return $functions;
  }

Remaining tasks

Agree about implementation, document new functions or existing functions changes, make sure they're backwards compatible.

User interface changes

None.

API changes

New Twig or changes to existing functions arguments.

Data model changes

None.

πŸ“Œ Task
Status

Active

Version

4.0

Component

Code

Created by

πŸ‡ΊπŸ‡¦Ukraine abramm Lutsk

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024