Render image or entity in a custom block! I want to render product content type in a custom block with a custom view mode. I have a field product_teaser in my article content type that reference the product that is I want to render in the custom block using advert view mode 

The content type to be rendered: "product"

The view mode to be rendered with: "advert"

The product teaser only contains an image and a buy=now button I can easily place using twig. So placing only the image in the render of the custom block should be enough for this to work But I have been trying to render the image for a while and I could not do it.



This is my first approach to do this, Rendering the whole product advert.

  public function build() {
    $node = \Drupal::routeMatch()-&gt;getParameter('node');
    if ($node instanceof \Drupal\node\NodeInterface) {
      $view_mode = 'advert';
      $product_id = $node-&gt;get('field_product_teaser')-&gt;getValue()[0]['target_id'];
      $product = \Drupal::entityTypeManager()-&gt;getStorage('node')-&gt;load($product_id);
      $view_builder = \Drupal::entityTypeManager()-&gt;getViewBuilder('node');
      $pre_render = $view_builder-&gt;view($product, $view_mode);
      $render_output = render($pre_render);
      return $render_output;
    }
    return [];
  }


Render output is an empty string for some reason. $pre_render has got view mode and node array having all the product fields, everything looks good except that render($pre_render) return an empty spaces string. 
This is the error being output from this approach "Argument 1 passed to Drupal\Core\Render\Element::isEmpty() must be of the type array, object given"



My second approach was to get the image URI of the product advert and render it manually

$build= array();      
    //Gets current node to check for which product to be displayed.
    $node = \Drupal::routeMatch()-&gt;getParameter('node');
    if ($node instanceof \Drupal\node\NodeInterface) {
      $product_id = $node-&gt;get('field_product_teaser')-&gt;getValue()[0]['target_id'];
      $product = \Drupal::entityTypeManager()-&gt;getStorage('node')-&gt;load($product_id);
      $product_advert_url = $product-&gt;field_teaser-&gt;entity-&gt;url();
    }


    $build['image'] = [
      '#theme' =&gt; 'image_style',
      '#style_name' =&gt; 'thumbnail',
      '#uri' =&gt; $product_advert_url
    ]; 

    return $build;


This is the error being output from this approach "Class name must be a valid object or a string in Drupal\image\Entity\ImageStyle->buildUri()"



How to fix these errors ??, I prefer the first method because it will be easier if I needed to add anything to the product teaser later.
You can do this in a View block. Add a contextual filter for the content id and configure it to provide the default value "Content ID from URL":



The view mode Teaser would be in your case a custom view mode (for the content type "article") only containing the product teaser field, configured to render the target entity in a second view mode "advert" (now for the content type "product"). 



If you want to do this in code, then get the node from a context plugin (see this great answer from @Berdir https://drupal.stackexchange.com/a/188629/47547) and build the render array (if you use the view modes mentioned above you only need one line of code). Very important, never render in Drupal 8, always return unrendered arrays.