Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query block: Add a configurable "no posts found" state #36609

Closed
jameskoster opened this issue Nov 18, 2021 · 14 comments
Closed

Query block: Add a configurable "no posts found" state #36609

jameskoster opened this issue Nov 18, 2021 · 14 comments
Labels
[Block] Comments Affects the Comments Block - formerly known as Comments Query Loop [Block] Query Loop Affects the Query Loop Block Needs Design Needs design efforts.

Comments

@jameskoster
Copy link
Contributor

This is particularly important for the search template in block themes. Currently, if a search returns no results then the query renders nothing on the frontend:

search.mp4

Ideally it should at least inform the visitor that no results were found for their search term. But it would be better to offer folks a way to customise this state with blocks.

Some design consideration will be required here, as blocks cannot currently entertain multiple states.

This affordance could also be useful in other scenarios:

  • Post Content block – enable users to control how password protected posts appear
  • Design separate empty / full states for Shopping Cart blocks in plugins like WooCommerce
  • Log in / out block – finer control of each state
@jameskoster
Copy link
Contributor Author

It's becoming apparent that many blocks will need to entertain multiple states, but one case that is particularly similar to this one is the Comments Query Loop.

When editing a template like Page or Single, it should not only be possible to compose comment lists, but also to design a state when no comments are found.

@jameskoster jameskoster added the [Block] Comments Affects the Comments Block - formerly known as Comments Query Loop label Jan 28, 2022
@ramonjd
Copy link
Member

ramonjd commented Feb 2, 2022

This is a tricky one.

We want whatever block/element we show to be part of the context in which we know there are no posts, e.g., post templates.

An all-encompassing approach eludes me right now: each block behaves a little differently.

Could we use a rich text field? This will entail adding attributes to the block. We could support two views, similar to how we handle placeholders, whereby the user could toggle the "no results" view in order to edit/preview it in the editor.

@carolinan
Copy link
Contributor

carolinan commented Feb 2, 2022

Adding my thoughts here, as previously added to the linked PR.

I have been thinking about how to make it configurable quiet a lot this week and even tried a few different things.
Some difficulties:
If we picture the "no results" as a container for other blocks so that the message can be customized:

  • A "no results" block needs to be available (placeable) in the editor even if there are results displaying in the editor, since the result on the front can depend on the query blocks "inherit from template" setting.
  • The no results block should not be repeated, and not placed inside the list element of the post template.
  • What inner blocks should be available for a no results block? What do users need, to be able to create a good no results found message? Perhaps all blocks should be available, including a second query block? (picture ecommerce sites that want to display other results if the first returns nothing.)

@ntsekouras
Copy link
Contributor

These are good thoughts @carolinan!

I agree that we might need a new block for this and as you mention there are many nuances (no duplicates, availability and available inner blocks, etc..). Maybe it could make sense as a menu item in block settings that would open a modal and edit that in a kind of isolated mode.

@carolinan
Copy link
Contributor

That makes me think that maybe, it should be a template "area" like header and footer.

@ntsekouras
Copy link
Contributor

ntsekouras commented Feb 2, 2022

That makes me think that maybe, it should be a template "area" like header and footer.

In the sense of handling yes, but in practice this is a block related functionality and can't be tied to a theme.

@markhowellsmead
Copy link

I'm attempting to include a workaround until this is supported correctly in core. Is there a way to add a custom block (server-side rendered) within the Query block, which accesses the query block to see whether there are any posts in the current selection? I've tried looking at the render_block filter, but I'm not sure how to access the details of the parent block.

@ramonjd
Copy link
Member

ramonjd commented Feb 17, 2022

I'm attempting to include a workaround until this is supported correctly in core. Is there a way to add a custom block (server-side rendered) within the Query block, which accesses the query block to see whether there are any posts in the current selection? I've tried looking at the render_block filter, but I'm not sure how to access the details of the parent block.

Hmmm interesting idea!

Maybe there should be some token on the container (data- attribute of something).

~The only thing that worked for me (and I didn't test very much) was drilling down through $block->parsed_block['innerBlocks'] and doing a count of 'core/post-title'.

Edit: but I realize that won't work given that it's not guaranteed that there'd be a post title 😆

Maybe we're looking at the wrong block. The Post Template block returns '' when the query is empty, so we know at that point that we need to do something.

If we wanted to render a block here, maybe we could allow a "special" block in the Post Template block; one that is only meant to show when the query is empty?

This prints out correctly for example:

	if ( ! $query->have_posts() ) {
		// Could this be a "special" block in the post-template block?
		// Accessible via $block->parsed_block somewhere?
		$parsed_blocks = parse_blocks(
			'<!-- wp:paragraph --><p>No posts for you!</p><!-- /wp:paragraph -->'
		);
		$no_results_block = (
			new WP_Block(
				$parsed_blocks[0],
				array()
			) )->render( array( 'dynamic' => false ) );

		return $no_results_block;
	}

Testing via the search page: http://localhost:8888/?s=blah

@carolinan
Copy link
Contributor

@markhowellsmead The query block does not know if there are any results, so it can't pass that data on. Which was part of the difficulty for me at first.
The only way I could do it was to run the query in the new block to check if there are any results or not.
You can check the PR, or look at the query pagination block.

Or , create a PHP template, render footer and header template parts, and then conditionally show different blocks depending if there are posts or not.

@carolinan
Copy link
Contributor

There are several problems with adding the block to the post template, already mentioned above, but one is that
you will get different results in the editor and front, depending on the query settings.
The search template does not know what the search query is, so the result in the editor is not accurate. The block can't be available only when the editor finds no results.

@stokesman
Copy link
Contributor

I'm glad this is being looked into!

@markhowellsmead, I used a render_block workaround. It doesn't allow customizing the message from the editor. I wouldn't call it pretty but it sufficed.

add_filter( 'render_block', function ( $block_content, $block ) {
    // For query blocks with the job-opening category that lack any results, insert
    // a message suited to the type of post.
    if (
        $block['blockName'] === 'core/query'
        && in_array( 3, $block['attrs']['query']['categoryIds'] )
        && trim($block_content) === '<div class="wp-block-query"></div>'
    ) {
        $block['innerContent'][1] = '<p>There are no current openings. Please check back soon.</p>';
        $block_content = implode('', $block['innerContent']);
    }
    return $block_content;
}, 10, 2 );

@markhowellsmead
Copy link

Thanks @carolinan, I'm going to look into implementing and testing your solution as a custom block. I'll let you know if I encounter any issues. (If anyone else is following along, it's #38806.)

@markhowellsmead
Copy link

If anyone wants to take it for a spin before it hits core, here's a standalone plugin which uses @carolinan's code: https://github.com/SayHelloGmbH/shb-query-no-results

@jameskoster
Copy link
Contributor Author

Closed by #38806

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Comments Affects the Comments Block - formerly known as Comments Query Loop [Block] Query Loop Affects the Query Loop Block Needs Design Needs design efforts.
Projects
None yet
Development

No branches or pull requests

6 participants