0

I want to programmatically create a block to which I can add a body field, a link and an image and then create a block twig template file where I can use these fields. For the uploaded image ideally I would want to be able to use a responsive image style. Am hoping someone someone can tell me how I would do this?

  • Why not use the field ui and the preinstalled image field type? And what do you mean by programmatically, you can do all things from the field ui in code as well. – 4k4 Jan 24 '18 at 17:46
  • I suppose I just want a one off custom block and don't necessarily want it to be a replicable thing. I have quite a few use cases where this would make more sense. Also it is better for pushing up the code using versioning – Leo Woods Jan 25 '18 at 0:18
  • Yes, there are pro and cons, but the biggest pro is IMHO the image handling of the field ui, which is hard to implement in own code. If you don't want to clutter the block system with a lot of custom block types it could make sense to create a custom entity type (Console generates a twig template for it automatically) and then use a simple block plugin to place the entity including the template in a custom block.. – 4k4 Jan 25 '18 at 7:27
  • Nice one thank you, that indeed makes a lot of sense, I shall give that a go – Leo Woods Jan 25 '18 at 11:56
  • Hi @4k4 Sorry I have tried to create an entity and bundles but I never am able to create something complete? What commands do I use to create an entity and bundle so that I can add fields to it? – Leo Woods Jan 30 '18 at 16:53
0

Probably the easiest way to do this is a block with a settings form.

When you place a block of this class via the block layout, you can add your information in the settings. To have another block with different settings, just place another block.

Some sample code:

 public function blockForm($form, FormStateInterface $form_state) {
    $form = parent::blockForm($form, $form_state);

    $config = $this->getConfiguration();

    $form['my_block_text'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Foo'),
      '#description' => $this->t('my desc'),
      '#default_value' => isset($config['my_block_text']) ? $config['my_block_text'] : '',
    );
    return $form;
  }
  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
    parent::blockSubmit($form, $form_state);
    $values = $form_state->getValues();
    $this->configuration['my_block_text'] = $values['my_block_text'];
  }
  public function build() {
    $config = $this->getConfiguration();
    $text = $config['my_block_text'];
    ...
  $block = [
   '#theme' => 'my_module_my_theme',
    '#my_text' => $text,
    ... 
  ]; 
  return $block;
}

For images / files, you can just use the standard file form type. The config will get the fid of the image. In the build, you will need to load the file entity and generate the URL to the file. (Lots of existing examples of this).

To get it all to twig, you will need to use a hook_template() implementation that defines the twig template and variables. Then pass it to the theme using the render array created in the block build code.

  • Thanks, I think I have got this far but I would like to be able to add an image field to the block and then to print a responsive image style version of this in a block.html.twig file – Leo Woods Jan 24 '18 at 15:44
  • Edited answer to reflect this. – CG Monroe Jan 24 '18 at 15:53

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.