2

When displaying a Webform inside a normal block (using admin/structure/block) Drupal manage to correctly cache the page, the HTTP header displays X-Drupal-Dynamic-Cache: HIT.

However we need to display this webform inside a paragraph so we tried the following :

  • use twig_tweak module and {{ drupal_block('webform_...') }}
  • programmatically put the block in a template preprocess like this :
$my_form = \Drupal\webform\Entity\Webform::load('contact_new');
$output = \Drupal::entityManager()
          ->getViewBuilder('webform')
          ->view($my_form);
$variables['contact_form'] = $output;

Both solutions seem to make the page uncacheable: X-Drupal-Dynamic-Cache: UNCACHEABLE.

What would be the correct way to put a block in a paragraph while make the page cacheable ?
How to mimic the standard block system to display a in our template ?

1 Answer 1

3

The Dynamic Page Cache needs to placeholder the dynamic part and it can only do so when it is built in a lazy builder:

/mymodule/src/WebformLazyBuilder.php

<?php

namespace Drupal\mymodule;

use Drupal\Core\Render\Element\RenderCallbackInterface;

class WebformLazyBuilder implements RenderCallbackInterface {

  public static function buildWebform($webform) {
    return  [
      'webform' => [
        '#type' => 'webform',
        '#webform' => $webform,
      ],
    ];
  }

}

Then you can put the lazy builder in a template preprocess hook:

$variables['contact_form'] =  [
  '#lazy_builder' => ['\Drupal\mymodule\WebformLazyBuilder::buildWebform', ['contact']],
  '#create_placeholder' => TRUE,
];

Blocks are placed in a lazy builder by default, see BlockViewBuilder::viewMultiple.

4
  • 1
    Your example code is making think we could provide optional lazy builder support for all webform instances. For example, we would add a '#lazy_builder': true property to the Webform element, which returns a lazy builder instead of the webform.
    – jrockowitz
    Commented Jul 2, 2020 at 15:50
  • @jrockowitz, that sounds like a great idea, the element base class is already implementing RenderCallbackInterface, so we could place the lazy builder callback directly in the webform element class.
    – 4uk4
    Commented Jul 2, 2020 at 16:12
  • Thank you, that is a great answer :)
    – tostinni
    Commented Jul 3, 2020 at 6:24
  • @4k4 see drupal.org/project/webform/issues/3164675
    – jrockowitz
    Commented Aug 11, 2020 at 21:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.