3

I have a block (in Drupal 8) that renders a field of a node. This is my build function:

public function build() {
  $node = $this->getNode();
  $build = array();
  $markup = array();
  $current_lang = \Drupal::languageManager()->getCurrentLanguage()->getId();

  if ($node && $node->hasTranslation($current_lang)) {
    $node = $node->getTranslation($current_lang);
  }
  else {
    $node = false;
  }

  if ($node) {
    $fieldsToRender = array(
      'field_slider',
    );

    $viewmode = 'default';
    $entityType = 'node';
    $display = $this->getEntityViewDisplay();
    $viewBuilder = \Drupal::entityTypeManager()->getViewBuilder($entityType);

    foreach ($fieldsToRender as $field_name) {
      if (isset($node->{$field_name}) && $field = $node->{$field_name}) {

        $displayComponentSettings = $display->getComponent($field_name);

        if (!is_array($displayComponentSettings)) {
          $displayComponentSettings = array();
        }

        $fieldRenderable = $viewBuilder->viewField($field, $displayComponentSettings);
        if (count($fieldRenderable) &&! empty($fieldRenderable)) {
          $rendered = render($fieldRenderable);

          if ('' !== $rendered) {
            $markup[] = $rendered;
          }
        }
      }  
    }

    if (count($markup)) {
      $build = array(
        '#type' => 'markup',
        '#markup' => implode("", $markup),
      );
    }
  }

  return $build;
}

When I dpm($rendered) after $rendered = render($fieldRenderable); it gives me the wanted markup, in which at some point is an inline style tag that comes from inside a paragraph's template.

For some reason though, the inline style tag is removed in the final block output. I thought it was maybe due to the filters in the page.html.twig but just rendering the region using {{ page.regionname }} makes no difference.

So, where (and why) does Drupal strip that style tag?

PS: I also noticed in the block version of the field strips the twig debug comments, while the above mentioned dpm output still contains them. So I guess it has something to do with how the block handles the build function's returned markup...

4
  • 1
    See drupal.stackexchange.com/questions/187765/…
    – Clive
    Jul 4, 2017 at 15:22
  • when you use inline_template, the markup is actually converted to text. so you have to use the |raw filter in that template. thanks!
    – Alex
    Jul 4, 2017 at 15:32
  • 1
    No, never use the |raw filter. If you don't render early you don't get in trouble, see the answer from @guilhom.
    – 4uk4
    Jul 4, 2017 at 15:36
  • 1
    Yes, raw is bad.
    – Kevin
    Jul 4, 2017 at 16:13

1 Answer 1

3

To complete Clive answer, you could directly use your $fieldRenderable variable into a new renderable array that you will return from your build() function.

Example (not tested) :

$build = [];
foreach ($fieldsToRender as $field_name) {
  // Do your stuff
  $build[] = $fieldRenderable; // you can put whatever you want for the key
}
return $build;

The render process is done when you return the $build variable.

4
  • this unfortunately doesnt work
    – Alex
    Jul 4, 2017 at 15:58
  • Did you put a key for the new array containing the fieldRenderable ? If $field_name is unique, you can use that and replace $build[] = $fieldRenderable by $build[$field_name] = $fieldRenderable
    – guilhom
    Jul 4, 2017 at 16:01
  • sorry for the confusion. i didnt work in the first place because i had that $rendered = render($fieldRenderable); put before which appearantly caused issues
    – Alex
    Jul 4, 2017 at 16:03
  • 1
    You don't need to call render on it, you only need to return a renderable array here. It will be done for you.
    – Kevin
    Jul 4, 2017 at 16:12

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.