This is the potential bug report either of Webform, Block Token or Drupal core, I'm not sure yet. I've already spent a while of debugging this, but without success.

Basically I've couple of webforms with simple fields, lets call it the main webform, and the other webforms. These webforms are exposed as token using Block Token module. In the main webform I've created Computed token field with value:

1:[block_token:webform:myform1];2:[block_token:webform:myform2];3:[block_token:block_content:custom]

The problem is that when I'm viewing my main webform, the content of two webform blocks aren't rendered, although my custom block is rendered.

On the page it-self the output is empty:

1:;2:;3:<div id="block-test" ...><h2>Test</h2>...</div>

But when dumping the element in template_preprocess_form_element I see two placeholders for webforms, and properly rendered custom block:

string '1:<drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=myform1&amp;1=full&amp;2" token="p8BOEzhVedaNVMwuFKbSbXYvHJtJev-99V8a_12Hv4A"></drupal-render-placeholder>;2:<drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=myform2&amp;1=full&amp;2" token="CLE9WQ_qWlsCNZws4dp3bfLQFegyeEcEOg9tM-jrNwI"></drupal-render-placeholder>;3:

<!-- THEME DEBUG -->
<!-- BEGIN OUTPUT from 'core/themes/classy/templates/block/block.html.twig' -->
<div id="block-test" class="block block-block-content block-block-content76289379-5e8a-4435-84ab-cc9f26eec38d">
  
      <h2>Test</h2>
'... (length=1707)

And this is what is rendered in template_preprocess_form_element for (string)$variables['children'] (with another test with one webform):

1::2

<!-- THEME DEBUG -->
<!-- THEME HOOK: 'input__hidden' -->
<!-- FILE NAME SUGGESTIONS:
   * input--hidden.html.twig
   x input.html.twig
-->
<!-- BEGIN OUTPUT from 'themes/custom/one_manchester/templates/form/input.html.twig' -->
<input data-drupal-selector="edit-myform1" type="hidden" name="myform1" value="1:&lt;drupal-render-placeholder callback=&quot;Drupal\block\BlockViewBuilder::lazyBuilder&quot; arguments=&quot;0=myform1&amp;amp;1=full&amp;amp;2&quot; token=&quot;p8BOEzhVedaNVMwuFKbSbXYvHJtJev-99V8a_12Hv4A&quot;&gt;&lt;/drupal-render-placeholder&gt;:2" />


<!-- END OUTPUT from 'themes/custom/one_manchester/templates/form/input.html.twig' -->

I've read that normally you would need to use renderRoot() instead of render() to render these placeholders correctly, I've found few places in Webform which had render() and replaced them with renderRoot(), but it didn't help. The same happens on default Drupal theme. I've tried to reproduce the problem on the clean Drupal 8, and then I couldn't.

My steps on the clean Drupal were:

    drush qd
    cd *drupal*/drupal
    drush -y en webform_ui block_token
    drush cr

Configuration steps (I hope they're in the right order):

1. Expose any block via block_token, e.g. go to /admin/structure/block/manage/bartik_powered and tick 'Create the token for this block'.
2. Create Test form and Save at /admin/structure/webform/add
3. 'Add element', 'Computed token', Title: Test, Computed value: Foo:[block_token:system:bartik_powered]
4. Create Test form 2 and Save at /admin/structure/webform/add
5. View webform, the block is rendered correctly.
6. Go to: /admin/structure/block, click 'Place block' under 'Content', add Webform/Webform, then Place block, type test_form in Webform and select previously created test form, and select 'Create the token for this block'.
7. Add another 'Computed token' (Test 2), with [block_token:webform:webform] as a value.
8. Check whether webform tokens are rendered correctly on the webform view.

However as mentioned above steps worked fine on the clean installation, not on another site, so I'm not sure what's the problem, there could be some extra filter enabled, or some other missing thing.

Potentially related issue: #953034: [meta] Themes improperly check renderable arrays when determining visibility

Related question: How to replace drupal-render-placeholder manually?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

kenorb created an issue. See original summary.

kenorb’s picture

Issue summary: View changes
kenorb’s picture

Issue summary: View changes
jrockowitz’s picture

I am not sure that placing a webform on page using webform block that is injected into the page using a block token is going to work. The most immediate issue besides the one noted above is preventing the form from being cached. A secondary issue is making sure all the form's libraries are properly loaded.

Another approach would be to create a text format filter that inserted a webform into a page. The syntax could be {webform:WEBFORM_ID}. I think using curly brackets would prevent conflicts with [webform] tokens.

I do feel that this is an issue for the Block Token module to address since Webform blocks are working without any problems.

I have done a lot of work with Text format filters in the past and creating a "Webform Filter" module is not a lot of work.

kenorb’s picture

Project: Webform » Block Token
Version: 8.x-5.0-beta15 » 8.x-1.x-dev
Category: Support request » Bug report
kenorb’s picture

Did another test, but focusing on block_token module, and I've interesting results from block_token_block_render function:

function block_token_block_render($bid) {
  $block = \Drupal\block\Entity\Block::load($bid);
  $block_content = \Drupal::entityManager()
    ->getViewBuilder('block')
    ->view($block);
  return drupal_render($block_content);
}

My $block_content is:

array (size=3)
  '#cache' => 
    array (size=4)
      'keys' => 
        array (size=3)
          0 => string 'entity_view' (length=11)
          1 => string 'block' (length=5)
          2 => string 'repairs_taps' (length=12)
      'contexts' => 
        array (size=0)
          empty
      'tags' => 
        array (size=2)
          0 => string 'block_view' (length=10)
          1 => string 'config:block.block.repairs_taps' (length=31)
      'max-age' => int 0
  '#weight' => int -9
  '#lazy_builder' => 
    array (size=2)
      0 => string 'Drupal\block\BlockViewBuilder::lazyBuilder' (length=42)
      1 => 
        array (size=3)
          0 => string 'repairs_taps' (length=12)
          1 => string 'full' (length=4)
          2 => null

What is actually rendered from above array via drupal_render():

object(Drupal\Core\Render\Markup)[1322]
  protected 'string' => string '<drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=repairs_taps&amp;1=full&amp;2" token="p8BOEzhVedaNVMwuFKbSbXYvHJtJev-99V8a_12Hv4A"></drupal-render-placeholder>' (length=205)

Then this is assigned to the token as per this line in block_token_tokens():

        $replacement = block_token_block_render($id);
kenorb’s picture

Status: Active » Needs review
FileSize
718 bytes