Make WordPress Core

Opened 5 years ago

Last modified 2 years ago

#47637 reopened defect (bug)

Enhance excerpt_remove_blocks to handle more types of group blocks

Reported by: kuchenundkakao's profile kuchenundkakao Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 5.2.2
Component: Posts, Post Types Keywords: needs-patch
Focuses: Cc:

Description

The function excerpt_remove_blocks only considers top-level Blocks in an allowed list for the autogeneration of excerpts. However, since there is now a Group Block in Core (and a lot of self-developed Grouping Blocks out there), this can lead to autogenerated Excerpts being empty although there is plenty of content within the Post.

I propose to add a new filterable "group blocks" array, which adds another level to be included in the autogeneration. Additionally, there should be a possibility to register a callback which can be used to generate a custom excerpt dynamically if needed for custom blocks.

Change function excerpt_remove_blocks to this:

function excerpt_remove_blocks($content){
    $allowed_inner_blocks = array(
        // Classic blocks have their blockName set to null.
        null,
        'core/freeform',
        'core/heading',
        'core/html',
        'core/list',
        'core/media-text',
        'core/paragraph',
        'core/preformatted',
        'core/pullquote',
        'core/quote',
        'core/table',
        'core/verse',
    );
	$group_block_excerpt_functions = array(
		'core/group' => 'parse_group_block_excerpt',
	);
    $allowed_blocks = array_merge( $allowed_inner_blocks, array( 'core/columns' ) );
    /**
     * Filters the list of blocks that can contribute to the excerpt.
     *
     * If a dynamic block is added to this list, it must not generate another
     * excerpt, as this will cause an infinite loop to occur.
     *
     * @since 4.4.0
     *
     * @param array $allowed_blocks The list of allowed blocks.
     */
    $allowed_blocks = apply_filters( 'excerpt_allowed_blocks', $allowed_blocks );
    $group_blocks   = apply_filters('excerpt_allowed_group_blocks',$group_block_excerpt_functions);
    $blocks         = parse_blocks( $content );
    $output         = '';
    foreach ( $blocks as $block ) {
		if(in_array($block['blockName'],$group_blocks,true)){
			//We have a group Block with no extra excerpt function
			$output.= parse_group_block_excerpt($block,$allowed_inner_blocks);
		} elseif(in_array($block['blockName'],array_keys($group_blocks),true)){
			//The Block registered a custom callback for autogenerating an Excerpt
			$output.=call_user_func($group_blocks[$block['blockName']],$block,$allowed_inner_blocks);
		} elseif( in_array( $block['blockName'], $allowed_blocks, true ) ) {
            if ( ! empty( $block['innerBlocks'] ) ) {
                if ( 'core/columns' === $block['blockName'] ) {
                    $output .= _excerpt_render_inner_columns_blocks( $block, $allowed_inner_blocks );
                    continue;
                }
                // Skip the block if it has disallowed or nested inner blocks.
                foreach ( $block['innerBlocks'] as $inner_block ) {
                    if (
                        ! in_array( $inner_block['blockName'], $allowed_inner_blocks, true ) ||
                        ! empty( $inner_block['innerBlocks'] )
                    ) {
                        continue 2;
                    }
                }
            }
            $output .= render_block( $block );
        }
    }
    return $output;
}

Add a function parse_group_block_excerpt

function parse_group_block_excerpt($block,$allowed_blocks){
	$output = "";
	if(!empty($block['innerBlocks'])) {
		foreach($block['innerBlocks'] as $inner_block){
			if('core/columns' === $inner_block['blockName']){
				$output .= _excerpt_render_inner_columns_blocks( $inner_block, $allowed_inner_blocks );
				continue;
			}
			// Skip the block if it has disallowed or nested inner blocks.
			foreach($inner_block['innerBlocks'] as $inner_inner_block){
				if (
					! in_array( $inner_inner_block['blockName'], $allowed_inner_blocks, true ) ||
					! empty( $inner_inner_block['innerBlocks'] )
				){
					continue 2;
				}
			}
		}
	}
	return $output;
}

After that, a custom block can register itself as an group block just by using


add_filter('excerpt_allowed_group_blocks','add_my_awesome_group_block_to_excerpt');
 
function add_my_awesome_group_block_to_excerpt($allowed_blocks=array()){
   $allowed_blocks[] = 'my-awesome/groupblock';
   return $allowed_blocks;
 }

or even by using a custom excerpt function for dynamic blocks by using

add_filter('excerpt_allowed_group_blocks','add_my_awesome_group_block_to_excerpt');
 
function add_my_awesome_group_block_to_excerpt($allowed_blocks=array()){
   $allowed_blocks['my-awesome/groupblock'] = 'my_awesome_group_block_custom_excerpt';
   return $allowed_blocks;
 }

(I hope i did this right as this is my first ticket)

Change History (18)

#1 @noisysocks
5 years ago

  • Keywords needs-patch added; 2nd-opinion removed
  • Milestone changed from Awaiting Review to Future Release
  • Summary changed from Enhance excerpt_remove_blocks: add group Blocks and give Block Developers the ability to define excerpts for their Blocks to Enhance excerpt_remove_blocks to handle more types of group blocks

See #46133 for necessary context here. @azaozz wrote a patch that has an exception for columns blocks, but this solution needs to be expanded to cover all core and non-core group blocks. This is especially important now that Gutenberg is adding different kinds of group blocks e.g. Group, Cover, Media & Text.

Yeah, thinking we will need to keep enhancing the way we auto-generate excerpts for posts and include all blocks that may have relevant text.

The challenge is that we only want "static text" and need to exclude dynamic blocks as they may cause infinite loop if trying to generate an excerpt, and in most cases they are not particularly relevant to the rest of the post.

Ideally we should parse all "text containing blocks" regardless if they are wrapped in "container" blocks. The current patch only looks one level deep in all whitelisted blocks, and has an exception for core/columns where it looks inside each column. This can be enhanced and perhaps can be done better. Planning to look at it again for 5.3.

#2 @noisysocks
5 years ago

#47602 was marked as a duplicate.

This ticket was mentioned in Slack in #core-editor by talldanwp. View the logs.


5 years ago

#4 @eherman24
5 years ago

It would be nice if there were a filter added to allow other blocks, beyond the core/columns block, to output excerpts. Some further discussion was going on in our CoBlocks Github repo https://github.com/godaddy/coblocks/issues/735

Adding a filter in wp-includes/blocks.php line 163 https://github.com/WordPress/WordPress/blob/master/wp-includes/blocks.php#L163 would be beneficial to allowing additional blocks to be run through _excerpt_render_inner_columns_blocks().

#5 @talldanwp
4 years ago

I've closed this issue from the Gutenberg repo as it's a duplicate of this, but there are some extra thoughts/validation for this problem there:
https://github.com/WordPress/gutenberg/issues/17078

This ticket was mentioned in Slack in #core by kuchenundkakao. View the logs.


4 years ago

This ticket was mentioned in Slack in #core-editor by kuchenundkakao. View the logs.


4 years ago

#8 @tschortsch
4 years ago

Any update on this? Would be great if the excerpt generation could be enabled for custom blocks which use the InnerBlocks feature.

This ticket was mentioned in Slack in #core by talldanwp. View the logs.


3 years ago

#10 @talldanwp
3 years ago

  • Milestone changed from Future Release to 5.7

This ticket was mentioned in Slack in #core by hellofromtonya. View the logs.


3 years ago

#12 @sabernhardt
3 years ago

#52427 was marked as a duplicate.

#13 @lukecarbis
3 years ago

  • Milestone changed from 5.7 to Future Release

This ticket was mentioned in Slack in #core by mamaduka. View the logs.


3 years ago

#15 @chaion07
3 years ago

  • Resolution set to duplicate
  • Status changed from new to closed

Duplicate of #52134.

Hi @kuchenundkakao! Thank you for reporting the issue. We reviewed the ticket during one of our [recent triage sessions]https://wordpress.slack.com/archives/C02RQBWTW/p1622525779146400. Based on the feedback from the team we have modified the information on the ticket.

#16 @chaion07
3 years ago

  • Resolution duplicate deleted
  • Status changed from closed to reopened

Updated the ticket information upon further consultation.

#17 @chaion07
3 years ago

#52134 was marked as a duplicate.

#18 @kuchenundkakao
2 years ago

Any update on this?

Note: See TracTickets for help on using tickets.