This MR adds a new "Custom Elements Block" Views display class.

This is useful if you want to place a Views block leveraging lupus_decoupled_blocks.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Dan.Ashdown created an issue. See original summary.

dan.ashdown’s picture

Status: Active » Needs review

fago made their first commit to this issue’s fork.

fago’s picture

Status: Needs review » Needs work

Tested this, but it's not fully working yet.

I've tried to improve the code so the block provides a proper CE response. When done so the block rendering should pick up the CE wrapped in the render-array. But it seems the views/block rendering pipeline wraps the render array somewhere, so it ends up markup instead of json still.

There is some "

<" wrapper added

"views_block__teasers_custom_elements_block_1": "<drupal-markup><div class=\"views-element-container contextual-region\"><drupal-block-view display-id=\"custom_elements_block_1\" pager=\"{&quot;total_pages&quot;:2,&quot;current&quot;:0}\"><node type=\"article\" view-mode=\"teaser\" title=\"Abico At Bene Jus Utrum\" created=\"1682611419\" slot=\"rows\"><div slot=\"body\"><p>Conventio jumentum luptatum nobis pecus proprius singularis ulciscor. Conventio genitus iustum nobis ulciscor vulputate. Dolor dolore dolus ibidem singularis. Causa gilvus ille macto os valde.</p>\n<p>Immitto iriure melior sed venio vindico. Elit importunus pneum quidem torqueo vel. Amet distineo hendrerit illum iriure jugis sino valetudo. Accumsan haero modo praemitto saepius. Distineo erat inhibeo roto verto virtus. Aliquam natu neo nulla tum velit vero. Antehabeo appellatio gilvus humo ibidem uxor vulputat

fago’s picture

Title: Views - Add a CE block display » Add support for views blocks
Priority: Normal » Critical

re-titling and raising prio

benellefimostfa made their first commit to this issue’s fork.

roderik made their first commit to this issue’s fork.

roderik changed the visibility of the branch 3363234-subrequests-request-uri-patch-8678 to hidden.

roderik’s picture

Rebased the old MR because the underlying code changed a lot with #3469398: When editing a custom elements page view php errors are produced by renderer (code was moved from the controller to CustomElementsPage plugin). Tested that output is the same as before.

The MR is not ready, because of now 2 reasons:

1) CustomElementsPage and CustomElementsBlock contain pretty much the same code though they extend different classes. This wants a trait.

2) The originally reported issue still exists. I need more time to properly comment on this, than I have right now.

roderik’s picture

Assigned: Unassigned » fago
Status: Needs work » Needs review
StatusFileSize
new210.16 KB

Mustapha did the tracing for this, and made a first change. I picked it up to check how exactly the change should be implemented (and to confuse myself on the way).

I've tried to improve the code so the block provides a proper CE response. When done so the block rendering should pick up the CE wrapped in the render-array. But it seems the views/block rendering pipeline wraps the render array somewhere, so it ends up markup instead of json still.

Yes, the block rendering does pick up the CE wrapped in some render array:

Build result

The call tree is:
1. LupusDecoupledBlockRenderer::getBlocks()
2. Drupal\views\Plugin\Block\ViewsBlock::build()
3. Drupal\views\Element\View::prerenderViewElement()
4. Drupal\views\ViewExecutable::executeDisplay()

4. returns the simple '#theme = custom_element' wrapper, and 2 + 3 add all the other stuff around it, to 'complete' the render array for a view.

(...) the block rendering should pick up the CE wrapped in the render-array.

I assume this means that you want to do a combination of two things:

A. pick the CE out of above ViewsBlock::build() structure;

B. set the CE instead of the rendered HTML, into $output[$region], in getBlocks(). (Until now, this is never done.)

About "B": OK, no further remarks.

re. "A": this feels to me like, at least in theory, 1) we could be throwing away part of the rendered output (produced by e.g. theme functions set by the block plugin; 2) we could be breaking compatibility by changing HTML output to something else. So I felt like I should put some thought into when exactly we are 'allowed' to do this:

  • If the CE is the only render-element-child, like this specific example? Sure. We can throw away the theme-wrapper function.
  • If there are several render-element-children, all CEs? Maybe, but...
  • ...what if there are several render-element-children, some of which are not CEs? We can probably renderRoot() the non-CE render-element-children individually, and add them as drupal-markup CEs (like is mentioned in #3353622: Improve CustomElement::createFromRenderArray() to better handle entites that render to custom elements)?
  • ...and what if they're not all first-level children? Do we need to recurse, then?

I've also seen #3353622: Improve CustomElement::createFromRenderArray() to better handle entites that render to custom elements, which proposes to do something like points 3+4 inside CustomElement::createFromRenderArray(). But thinking about the above points just confused me.

So, in the end, I added only the first bullet point, directly into getBlocks(). That's what we need right now. And I can't justify the testing time for making this more generic / decide how 'backward compatible' the other cases should be... unless I'm explicitly told that we should address those cases now.

@fago see MR. Is this the code change you want? Or am I misinterpreting some things?

fago’s picture

Status: Needs review » Needs work

93475a99 - Make LupusDecoupledBlockRenderer return a CE instead of HTML for some blocks.

I've no clue how/why this relates to this improvement. If the block-layout support has issues, please open a dedicate issue and move the code there. We can also use layout-builder and place the block to make sure it works. That'S the main use-case anyway.

(...) the block rendering should pick up the CE wrapped in the render-array.

I assume this means that you want to do a combination of two things:

NO, neither A or B shall be done here, ideally. We need to make sure the block provides a proper render-array with custom element - as documented - and it all shall work with that. If not, that's separate bugs to fix/open, but for layout-builder it definitely works.

The output of the above render array below "views_build" looks good, if this is the block's render array, it's all good. if the whole thing is the blocks render-array we need to change it, ideally from our views-plugin, to provide only the main-part we need.

Finally, we need to include test-coverage, i.e. a view with block + verified it renders correctly. Best we ship some layout-builder config that embeds it + test it works as it should.

fago’s picture

Assigned: fago » Unassigned
benellefimostfa’s picture

StatusFileSize
new227.71 KB

Whatever we do in the views Plugin, it's always wrapped by the block build in the getBlocks function,
However when I dump the rendered custom element in the getblocks here:

 $customElement = CustomElement::createFromRenderArray($render)
            ->toRenderArray();
dump( $customElement);
          $output[$region][$block->id()] = $this->getrenderer()
            ->renderRoot($customElement);

we get this custom element Array which looks correct to me, right?

custom elements dump

fago’s picture

The code looks mostly good now!

However, as discussed with roderik, the remaining todo is that we need to unwrap the resulting custom-element. It seems the views-block integration results into some render-array wrapper, what we need to get rid off, such that the API contract is on the block-level holds.

fago’s picture

Status: Needs work » Needs review
Issue tags: +Needs tests

ok, I got things working now. I refactored the code such that both display plugins, page and block, use the regular views control view for rendering. Before we have been bypassing it, instead of implementing render(). That's fixed now.

One thing that does not yet work, is the overridden title.
Then, we probably want to improve the custom-element tag to append the display id. But since this is a change for the page also, I think this should be its own change notice.

Also, this still needs a test. Meanwhile, this could be already reviewed.

Another follow-up we should open is a better preview, that actually does not render the HTML, but shows it. We could check our RSS feeds or JSON display plugins are doing that.

fago’s picture

ok, some more updates:
* Fixed block title overrides
* Fixed php8.1 compatibility
* Add config schema

Now, we just need to add test. Then this should be complete.

fago’s picture

Issue tags: -Needs tests

ok, I've added the test coverage also. I shortly tried doing a kernel test, but somehow the setup made troubles, so I extended the pre-existing functional test for the page instead. Next, I added follow-ups for the related issues and improvements I found and mentioned before. So this should be ready now.

arthur_lorenz’s picture

Status: Needs review » Needs work

MR looks good and generally this is working. I created a view, added a CE-Block display and added the block to the block layout. I tested that the title aswell as the number of results can be overridden ✅

However I came across a couple of UX issues during testing:

  • When no view title is set (which is the default) an empty title attribute is rendered. What about using the view's name as fallback?
  • All view formats other than Custom Elements don't show any results. Should we limit the options?
  • The Display Title option in the block configuration does not have any effect

Since those are minor issues, should we move them to follow up issues?

fago’s picture

Status: Needs work » Needs review

> When no view title is set (which is the default) an empty title attribute is rendered. What about using the view's name as fallback?

hm, interesting. I'd leave it up to the frontend to make this fallback if desirable. When we set the view name it's hard for the frontend to differentiate from a real title, so it should be done there imo. When no view title is given/set, an attribute seems ok / honest to me.

> All view formats other than Custom Elements don't show any results. Should we limit the options?
Sounds good, but I don't know whether this is feasible. I'd suggest this is a follow-up improvement + applies to pages also.

> The Display Title option in the block configuration does not have any effect
Good point. So maybe we should hide that option? Imo, we could do this as a follow-up improvement.

arthur_lorenz’s picture

Status: Needs review » Reviewed & tested by the community

Alright -> RTBC then

  • fago committed ed0ba860 on 1.x authored by dan.ashdown
    Issue #3354675 by fago, roderik, arthur_lorenz: Add support for views...
fago’s picture

Status: Reviewed & tested by the community » Fixed

thx, merged then!

Also created follow-up for #3520511: "display title" option for view blocks does not work.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.