Moving post title down the page / Removing a block from a post


I work on a portfolio site where the graphic designer wants a carousel at the top of the page, above the page title and the rest of the content. When she creates a page in the backend, it looks normal (title, carousel, content) and she understands that it will look differently on the frontend (carousel, title, content).

In the shortcode days, I accomplished this by:

  1. Using a regex in the theme’s content.php to find the shortcode and call do_shortcode on it. This happens before the call to the_content on the page.
    $regex = '/[carousel[^]]*id=['"](.*)['"]?[^]]*]/';

    if ( preg_match_all( $regex, $post->post_content, $matches ) )
    { echo do_shortcode($matches[0][0]); }

    the_title( '<h2 class="entry-title">', '</h2>' );
    the_content( 'Continue reading...', false );
  1. In the theme’s functions.php, create a filter on the_content to remove the shortcode.
function carousel_remover( $content ) {
    if ( has_shortcode( $content, 'carousel' ) ) {
        $regex = '/[carousel[^]]*id=['"](.?)['"]?[^]]*]/';

        if ( preg_match( $regex, $content ) ) {
            // Filter the shortcode out of the_content
            $content = preg_replace( $regex, '', $content, 1);
    return $content;
add_filter( 'the_content', 'carousel_remover' );
  1. When the_content is called in content.php, the shortcode has been removed. So, the order everything is rendered becomes: shortcode, title, all the rest of the content.

The carousel plugin was recently updated with a Gutenberg block and this process doesn’t work with blocks.

I added a regex to match the block code in content.php, pull out the post ID, and call do_shortcode on it. That works, and the carousel is rendered above the title.

However, removing the block code in functions.php does not work. Some log dumping shows that when the content is passed to the the_content filter, the block has already been rendered to HTML. So the browser gets carousel, title, carousel, content. I also tried removing the block in content.php but this doesn’t work either:

if  ( has_block( "client/carousel" ) ) {
        $blocks = parse_blocks( $post->post_content );
        foreach ( $blocks as $block ) {
            if ( 'client/carousel' === $block['blockName'] ) {
                $num = $block['attrs']['id'];
                $regex_gutenberg = '/<!-- wp:client/carousel {"id":"(.*)"} /-->/';
                $post->post_content = preg_replace( $regex_gutenberg, '', $post->post_content, 1 );
                echo do_shortcode("[carousel id='".$num."']");
                break; // Only do this for the first carousel block found...

The block is removed from $post->post_content, but it’s still rendered when I call the_content.

Where do I hook in to remove the block before the content is rendered? Or is there perhaps an easier method to move the title down below the first carousel?

Thank in advance for the advice.

JohnW 2 years 2020-12-29T15:10:45-05:00 0 Answers 3 views 0

Leave an answer