I have quite a bit to ask in this question, so I apologize in advance. I believe these questions are all related, and I'm trying to grasp some thoughts on the new block system in Drupal 8.

Background

I am troubleshooting a custom block implemented by a vendor. This block is not listed in the Custom block library, but I can add it to the page with the Place Block link on the Block layout page (note: this makes me think it's an "old-style" block, as in D7 type block). When I place a new block, I am presented with a "Configure block" screen, which I believe shows and stores the values of these fields in config. The custom class extends BlockBase, so the form I'm seeing is built/shown/processed with blockForm() and blockSubmit() in the code.

The problem I am having is that files/images added via these "config" fields (aka a form file upload field, or a wysiwyg editor's IMG button) upload "temporary" files to the file system, which are then later deleted as orphans by a cron run a few hours later. I realize I can turn off that cron job, but I am looking for a BETTER solution. When I go to the files page (/admin/content/files), I want to see that my uploads are "used in" at least one place, and have that place show correctly as a link to the block. My belief, is that if this block were built as a custom block type, using fields, that Drupal would by default take care of the association of these images, which really are content.

Questions

So this brings me to some questions... Am I on the right path here? Should I be using fieldable, custom blocks for this implementation? If the image is a field, and the body is a field, and saved appropriately in the database, then the files page will be able to see this content correctly. This is do-able, correct?

So this brings me to my next question, when should I be using blocks/configuration and when should I be using blocks/fields? This particular example screams "content" at me, and in that case, I think the argument is for fields. Does that sound right? I can think of another example off the top of my head that I'm a little more fuzzy on. We offer a custom block for "Polls" on our website where, when creating a new poll, you choose a reference to a poll, and can optionally set (override) the Title shown in the block. That's 2 settings that a site admin should be able to change. Are these still content, or are they config? To me, it seems like the "poll reference" could go either way... I assume most custom blocks have some combination of "content/fields" AND "config", right? For example, all the "Visibility settings" for a block get saved as config, right?

Any help understanding all of this is much appreciated! Thank you!

  • Note: this question/answer was helpful, but doesn't give me everything I need. I'm a little confused if my block code counts as a "plugin" or not...? – Dave Aug 4 '16 at 20:52
up vote 1 down vote accepted

What you describe are three different things:

  1. If you put code in a class that extends BlockBase, then yes, this is a block plugin.

  2. If you add a custom block in the block library, then you store content in the database as block_content.

  3. If you place a block in the block library then you add a block configuration, this is a config entity with the name block.

In a block configuration (3) there can be either a plugin (1) or a block content (2).

You can configure fields in (2), then the storage will be managed by drupal, also for image fields.

If you put form fields in (1) then they are not content, but config. You need submit code to handle this. The result of a file field remains temporary until you decide to save it. And combining config with an uploadable file seems a bit odd, but is possible, see for example the site logo.

Comparing both, I would start with (2) and only use (1) if I need code to make something that (2) does not provide.

Edit: Answer to the comment

If you use (2) you probably should be able to solve most of the tasks you describe in the comment in theming (preprocess + twig).

If not, there may be a solution by using (1) + (2). Put the image in block content (to store it properly in the database), but then use this not as a custom block as in (2), but pull the data in your own plugin. For this put a field in blockForm() to configure the block content id and then use in build() the entity api to load the field data of the configured id.

In fact drupal does the same to get the block content entity into a block, it uses also a plugin for this, but you would make your own.

  • Thanks @4k4. So my block does need to do quite a bit of custom work such as looking at an attribute of the current user, and changing the display based on that attribute by pulling related entities. It also dynamically displays some of those "content" fields as well depending on these values. That to me sounds like the way it was done is correct, but this leaves me with the "file usage" problem I describe. I assume there is not a good way to get around that? – Dave Aug 8 '16 at 14:39
  • See the edited answer. – 4k4 Aug 8 '16 at 16:06

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.