0

The FilterProcessResult::createPlaceholder method suggests that I can set a PHP callable that will allow me to return a render array. However my callable is not being called when visiting a node using Drupal 8.0.x.

I do not see any error messages in watchdog or in the PHP log.

What should I be doing in order to get FilterProcessResult::createPlaceholder() to call my callable?

Code

  public function process($text, $langcode) {
    $matches = [];
    $result = new FilterProcessResult($text);

    $count = preg_match_all('/\[processing\](?P<code>.*)\[\/processing\]/is', $text, $matches);

    if ($count) {
      $i = 0;
      foreach ($matches['code'] as $i => $code) {
        $args = [$code, $this->settings['render_mode']];
        $markup = $result->createPlaceholder('\Drupal\processing\Plugin\Filter\FilterProcessing::build', $args);
        $text = preg_replace('/\[processing\](?P<code>.*)\[\/processing\]/is', $markup, $text);
      }
      $result
        ->setProcessedText($text)
        ->setAttachments(['library' => ['processing/drupalprocessing']])
        ->setCacheTags(['processing']);
    }

        return $result;
      }

  static public function build($script, $mode) {
    $id = uniqid('processing-');
    $canvas_classes = ['processing-js-canvas', 'processing__canvas'];
    $render = [
      '#type' => 'container',
      '#attributes' => [
        'class' => ['processing-wrapper']
      ],
      'canvas' => [
        '#theme' => 'processing_display',
        '#rendermode' => $mode,
        '#unique' => $id,
        '#code' => $script,
        '#attributes' => [
          'class' => $canvas_classes,
          'id' => $id,
        ],
        '#attached' => [
          'drupalSettings' => [
            'processing' => [
              'drupal.processing' => [
                'elementId' => $id,
                'renderMode' => $mode,
              ]
            ]
          ]
        ],
      ],
    ];
    return $render;
  }

See commit 9d84e9477515bce1b7dd15f9724da1c6c0bd0fc2

HTML Output

<drupal-filter-placeholder callback="\Drupal\processing\Plugin\Filter\FilterProcessing::build" arguments="0=%0A%20%20%20%20%20%20%20%20size%28200%2C%20200%29%3B%0A%20%20%20%20%20%20%20%20background%28200%29%3B%0A%20%20%20%20%20%20&amp;1=source" token="bd5dbeba"></drupal-filter-placeholder>

I am running a settings.local.php with cache disabled on a local VM, but I got the same result without it.

1

After several months, I looked at the code again and found the issue. The createPlaceholder method calls addAttachments, but then I call setAttachments, which removes the previous attachment.

I should always use addAttachments as that will merge instead of overwrite.

foreach ($matches['code'] as $i => $code) {
  $args = [$code, $this->settings['render_mode']];
  $markup = $result->createPlaceholder('\Drupal\processing\Plugin\Filter\FilterProcessing::build', $args);
  $text = preg_replace('/\[processing\](?P<code>.*)\[\/processing\]/is', $markup, $text);
}
$result
  ->setProcessedText($text)
  ->addAttachments(['library' => ['processing/drupalprocessing']])
  ->setCacheTags(['processing']);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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