Problem/Motivation
Referenced block entities (not content blocks) do not show up when rendered UNLESS they are visible anyway in some region.
This is due to access and visibility check.
Proposed resolution
Add an entityreference formatter option "ignore access checks" that opens a sitebuilder the possibility to solve this.
Remaining tasks
Check if this is feasable.
Hack it.
User interface changes
Additional formatter option.
API changes
TBD
Data model changes
TBD
Original Report
When an entity reference field references a block, and the field formatter is set to render item, the block will only be visible if it is already placed in a region on the theme block administration page. It should be possible to view the block even if the block is not generally visible in a region.
Steps to reproduce:
- Create a entity type (node, taxonomy term, block etc.) with an entity reference field
- Set target entity type to block
- Set field formatter to rendered entity
- Create a custom block that is not visible in a theme region
- Reference the block from your content type
- The referenced block will not be visible
This can be useful in many cases. I need it to create blocks with tabbed content (blocks within a block).
The reason for the problem is that the block module checks for each block's status. If it is not active in the current theme, it will be marked with status = FALSE. Then in the access check of the block module the access to the block is not permitted and the block is not rendered.
It is pretty easy to make a fix for this by implementing hook_ENTITY_TYPE_load() and set status to TRUE. However, I think a better way is to change core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceFormatterBase.php to set the status to TRUE if the entity has the setStatus method enabled. But this approach does not work as the access to the block has already been checked and cached. So it would be necessary to invalidate the cache.
Can anybody see a nice solution to this?
Comments
Comment #1
cilefen commentedComment #2
alexej_d commentedI can confirm this bug. It is a major flaw. The only workaround right now would be to create a region you would not render anywhere and add your blocks to it before you can reference them…
Comment #3
tim.plunkettThere is a difference between a custom block (block content) and a block entity. Which entity are you referencing?
You should be referencing the custom block, not the block entity.
Comment #4
bjaxelsen commented@tim.plunkett: I am not quite sure I understand the question: In my case I created a block and referenced other blocks (two Views blocks) and only the Views block that was otherwise visible (placed in a region of the theme) was rendered. The other View block was not rendered (it has status = FALSE and will be hidden).
Should I supply some yaml files of the blocks and views, or could any other details clarify the issue?
Comment #5
alexej_d commented@tim.plunkett There are several use cases when you want to reference a views block or a config entity type block supplied by a module (so yes, we are not dealing with content entities). Both types can only by referenced successfully once you add them to a region.
Comment #6
tim.plunkett#2513534: Remove the 'disabled' region from Block UI will force you to have a region.
Comment #7
berdirYeah, using entity reference to reference block configs is just not a very good match I think. entity reference checks access and that includes visibility settings and so on.
One possibility would be to write a formatter just for block configs that doesn't care about access. But it's still very weird to have to configure dummy blocks to then use them in a completely different way.
Something that builds on top of plugin field types provided by http://drupal.org/project/plugin might make a lot more sense. Then you'd select a block *plugin* and can configure it on the spot, just like the block config form. That's a lot closer to how e.g. page manager uses blocks as well.
Don't really think this is a bug (that we need to solve in core). Just because an entity reference can reference any entity type doesn't mean that every option needs to actually work. It can't render views either, for example.
Comment #8
alexej_d commented@Berdir so you think it is acceptable that a core feature is not working most of the time? Wouldn't it be better to completely remove the feature to reference config entities since it does not work as expected?
Still, in my opinion it would be a killer feature to reference views and views blocks and it is really something you would expect from the entity reference field. But it is probably to late to get that into core :(
Comment #9
amateescu commentedYou can reference views and blocks just fine with the core ER field, the problem is how you display a config entity since most of them are not meant to be "viewed". I also proposed the custom formatter solution in IRC yesterday but.. I'm not so sure about it anymore :)
Edited: see next comment.
Comment #10
amateescu commentedOn the other hand, disabling the "Rendered entity" formatter if the ER field references a config entity probably makes more sense, since config entities do not have an entity view builder (i.e. they are not meant to be "rendered/viewed").
Edit: I just remembered that the block config entity does have a view builder, which is complete nonsense :(
Comment #11
berdirWell, block entities can be viewed :)
And we already do exactly that:
Comment #12
amateescu commentedYeah, it's been a while since I looked at the code :/ Anyway, the gist of the problem is that blocks have a view builder and they shouldn't.
Comment #13
xanoThis is indeed possible, but #2532968: Block plugin forms assume they are top-level prevents block plugin configuration from being stored at the moment. We're working on fixing this.
Comment #14
alexej_d commentedI think if a config entity has an own view builder (like blocks) it should be renderable using the entity reference formatter, any other behaviour is really just irritating and will lead many new Drupal developers to the conclusion that something is broken (making them loose time trying to fix it).
Comment #15
badrange commentedI lost time today apparently due to this issue. With Drupal 7 I have at a couple of occasions created a view block, and used the block reference module to add fields where I allow editors to choose which of their favourite blocks are rendered on a node (typically view blocks, can be any block).
Pretty neat solution if you'd like the editors to be able to choose which listings shows up on the front page with a minimum amount of configuration, they can take the news listing, event listing etc.
Block reference has a D8 issue at (https://www.drupal.org/node/2410289) where one of the commenters points out this:
but it doesn't really work, does it - in my case I either get two copies of the block on a page (placed both through the reference AND through blocks layout page, or none.
Comment #17
jojonaloha commentedI was just playing with creating an Entity Reference to a View and the only formats available are Label and Entity ID. I think amateescu is right in #9 that it doesn't make sense to render MOST config entities, but there are some that do render. Like Blocks and Views. In those cases I think it also makes sense to allow Contrib to come up with the custom Field Formatters for those things. Ideally those two specifically could be moved into core.
So, my question is, does anybody know of a contrib or sandbox module that has a Entity Reference Field Formatter for Views config entities?
All I keep getting is https://www.drupal.org/project/views_field_formatter and https://www.drupal.org/project/entityreference_views_formatter which don't seem to be what I'm looking for.
Comment #18
jasonawant@jojonaloha,
There are few options out there.
Viewfield: https://www.drupal.org/node/2220929
Sandbox project Entity reference view formatter: https://www.drupal.org/sandbox/paulmckibben/2481503
Entity Views Attach: https://www.drupal.org/node/1937618
Core, Add a ViewBuilder for Views: https://www.drupal.org/node/1857422
Comment #19
jojonaloha commentedThank you @jasonawant, those look promising! I'll evaluate those to see which seems most viable for my project.
Comment #21
jibranClosing it as per #7 and #12. Feel free to re-open it you disagree. Meanwhile you can use DsField to add a block from https://www.drupal.org/project/ds.
Comment #22
geek-merlin@jibran #21:
> Meanwhile you can use DsField to add a block from https://www.drupal.org/project/ds.
I did not see how you can override access here - can you?
Comment #23
geek-merlinSo the use case is to render a referenced block that is in no visible region.
The conslusion is "not possible because of access checks".
So the most natural thing is to bring back tha D7 entityreference formatter option to "ignore access checks".
Comment #25
d.fisher commentedI'm not sure if something has changed since the last time I visited this issue.
To fix this issue on a previous project (using Drupal 8.2.4) I created a "reference" region in my theme info file and place a block in it which didn't get rendered in my page.html.twig. I would then create an entity reference field on the node and select the specific block I'd placed in the "reference" region and the block would magically render. It was somewhat messy having to follow these steps but at least it worked.
Now using Drupal 8.2.6 this doesn't seem to work any more. The block doesn't render.
: (
Comment #26
d.fisher commentedIgnore my previous comment. I was referencing a block that had anonymous only permissions on it and I was logged in!!!
So to confirm for anyone wanting to resolve this issue for now (just elaborating on comment #2 from @alexej_d).
Hope that helps somebody until this issue makes further progress.
Comment #27
berdirThere are various projects that offer to select a block plugin directly now, without going through creating a block placement first with some strange hacks. Note that all those things cause overhead because Drupal will prepare such blocks, check access for them and so on on every page.
See https://www.drupal.org/project/block_field for example, which is working quite well for us, it also easily allows to limit access to just a few blocks or just select one by default and then you can use field permissions to hide it for users.
Comment #28
d.fisher commentedI didn't know about this module. Looks good. I'll check it out. Certainly feels like a nicer solution than hacking a region which doesn't render.
Comment #29
drupalmonkey commentedBlock Field module seems to be working well for us as well.
Comment #33
VishalKumarSahu commentedI am experiencing the same issue and not getting any theme_preprocess function to solve the issue.
The way I am trying to render is Darren Fisher's comment [#26].
Other threads with similar issues are-
https://www.drupal.org/project/drupal/issues/2704331
https://www.drupal.org/project/drupal/issues/2730217
Comment #44
smustgrave commentedThank you for sharing your idea for improving Drupal.
We are working to decide if this proposal meets the Criteria for evaluating proposed changes. There hasn't been any discussion here for over 8 years which suggests that this has either been implemented or there is no community support. Your thoughts on this will allow a decision to be made.
Since we need more information to move forward with this issue, the status is now Postponed (maintainer needs more info). If we don't receive additional information to help with the issue, it may be closed after three months.
Thanks!
Comment #45
berdirThis was already closed in 2016. I disagree that the UI should offer an option to bypass access, if someone wants that they can do that in contrib. 10 years later, we also have various alternatives and replacements for this with canvas and layout builder and what not that clearly people haven't been needing this.