title: Drupal 8 how to save and render an image using a custom block configuration
body: <p>I'm trying to create a custom module with configuration for a block that will allow a block to have custom fields. I'm having problems allowing the upload of an image and then rendering this in the block on the site.</p>
  
  <p>Currently this is what my block file looks like;</p>
  
  <p>
  
  <p>use Drupal\Core\Block\BlockBase;
  use Drupal\Core\Form\FormStateInterface;</p>
  
  <pre><code>/**
   * Provides a 'hello' block.
   *
   * @Block(
   *   id = "hello_block",
   *   admin_label = @Translation("Hello"),
   *   category = @Translation("Hello world block")
   * )
   */
  class HelloBlock extends BlockBase
  {
  
      /**
       * {@inheritdoc}
       */
      public function blockForm($form, FormStateInterface $formState)
      {
          $form['heading'] = array(
              '#type' =&gt; 'textfield',
              '#title' =&gt; t('Heading'),
              '#description' =&gt; t('Enter the main heading'),
              '#default_value' =&gt; 'Main heading'
          );
  
          $form['sub_heading'] = array(
              '#type' =&gt; 'textfield',
              '#title' =&gt; t('Sub heading'),
              '#description' =&gt; t('Enter the sub heading'),
              '#default_value' =&gt; 'Sub heading'
          );
  
          $form['body'] = array(
              '#type' =&gt; 'text_format',
              '#title' =&gt; t('Body'),
              '#description' =&gt; t('Main body'),
              '#format' =&gt; 'full_html',
              '#rows' =&gt; 50,
              '#default_value' =&gt; ''
          );
  
          $form['image'] = array(
              '#type' =&gt; 'managed_file',
              '#upload_location' =&gt; 'public://upload/hello',
              '#title' =&gt; t('Image'),
              '#upload_validators' =&gt; [
                  'file_validate_extensions' =&gt; ['jpg', 'jpeg', 'png', 'gif']
              ],
              '#default_value' =&gt; isset($this-&gt;configuration['image']) ? $this-&gt;configuration['image'] : '',
              '#description' =&gt; t('The image to display'),
              '#required' =&gt; true
          );
  
          return $form;
      }
  
      /**
       * {@inheritdoc}
       */
      public function blockSubmit($form, FormStateInterface $formState)
      {
          $this-&gt;configuration['heading'] = $formState-&gt;getValue('heading');
          $this-&gt;configuration['sub_heading'] = $formState-&gt;getValue('sub_heading');
          $this-&gt;configuration['body'] = $formState-&gt;getValue('body');
          $this-&gt;configuration['image'] = $formState-&gt;getValue('image');
      }
  
      /**
       * {@inheritdoc}
       */
      public function build()
      {
          $markup = '&lt;h1&gt;'.$this-&gt;configuration['heading'].'&lt;/h1&gt;';
          $markup .= '&lt;h2&gt;'.$this-&gt;configuration['sub_heading'].'&lt;/h2&gt;';
          $markup .= '&lt;img src="'.$this-&gt;configuration['image']['value'].'"&gt;';
          $markup .= '&lt;div&gt;' . $this-&gt;configuration['body'] . '&lt;/div&gt;';
  
          return array(
              '#type' =&gt; 'markup',
              '#markup' =&gt; $markup,
          );
      }
  }
  </code></pre>
  
  <p>Can anyone provide some pointers as to why the image isn't appearing? I'm assuming I'm missing something.</p>
  
  <p>The text saved in the body (text_format) also appears in the block on the website as 'array', if anyone can help with that too it would be good, other wise I'll raise another question.</p>