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.– 4uk4Commented Jan 24, 2018 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 WoodsCommented Jan 25, 2018 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..– 4uk4Commented Jan 25, 2018 at 7:27
-
Nice one thank you, that indeed makes a lot of sense, I shall give that a go– Leo WoodsCommented Jan 25, 2018 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 WoodsCommented Jan 30, 2018 at 16:53
1 Answer
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 Commented Jan 24, 2018 at 15:44
-