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

[bw_fields] shortcode not displaying values after first query-loop post #28

Open
bobbingwide opened this issue Nov 10, 2020 · 5 comments
Assignees
Labels
bug Something isn't working enhancement New feature or request

Comments

@bobbingwide
Copy link
Owner

bobbingwide commented Nov 10, 2020

While testing a solution for issue #27 I started changing the home-query.html template part.
I wanted to use the metadates.html template part to replace the rather complicated ( and ugly ) columns block that I'd used to display Published and Last updated dates.

I noticed that for the second and subsquent posts in the query-loop the [post-edit] shortcode worked but the [bw_fields] ones did not. get_edit_post_link() calls get_post() to find the current post ID.
But the logic for [bw_fields] currently prevents the shortcode from doing anything when the current post is not the global post.
This was done to prevent a sidebar on an archive page from displaying the wrong information.

Proposed solution

I don't want to revert the change to [bw_fields].
If we extend [bw_fields] to work when the id attribute is '.' then this might resolve this problem.

Originally posted by @bobbingwide in #27 (comment)

@bobbingwide bobbingwide self-assigned this Nov 10, 2020
@bobbingwide bobbingwide added bug Something isn't working enhancement New feature or request labels Nov 10, 2020
@bobbingwide
Copy link
Owner Author

Looking at the code for oik-fields I noticed that the [bw_field] shortcode had not been changed to check the current post ID.
The easiest solution is to change the metadates.html file to use [bw_field ]

<p>Published: [bw_field post_date] | Last updated: [bw_field post_modified] [post-edit]</p>

Note: Since this isn't a properly constructed paragraph block the Site Editor may have problems with it.
Check first, then fix.

@bobbingwide
Copy link
Owner Author

bobbingwide commented Mar 11, 2023

Retesting with WordPress 6.2-RC1 and Gutenberg 15.3.1 I believe I'm getting a different problem.

  • The [bw_fields] shortcode is getting the wrong post ID.
  • The shortcode expansion is not being performed within the query block but afterwards.
  • I thought this could be something to do with oik-css changing the priority for do_shortcode, but deactivating oik-css didn't change the processing.

The explanation is that the shortcodes block's rendering function doesn't actually expand the shortcode.
There are two similar issues for this

  1. Query Block: Current post ID WordPress/gutenberg#35676
  2. Query block with shortcode breaks get_the_ID or get_post WordPress/gutenberg#43053 - similar issue but it suggests a solution to the problem of using shortcodes inside the query block.

The solution is to change the shortcode block so that it actually expands the shortcodes within the query block's loop.

function render_block_core_shortcode( $attributes, $content, $block ) {
	$result = wpautop( $content );
	return do_shortcode($result);
}

When the shortcode is being expanded calls to get_the_id() will obtain the correct post ID.

When the shortcodes are left unprocessed until the template's blocks have been rendered then the context of the current post ID returns to the main post.

For Fizzie, I can override the rendering of the shortcode block using

function fizzie_render_block_core_shortcode( $attributes, $content, $block ) {
	bw_trace2();
	$html = do_shortcode( $content );
	return $html;
}

I can't see any need for wpautop().

Note: This solution will not work for shortcodes which are in other blocks such as the paragraph block.
To cater for these it would be necessary to do_shortcode() within the query loop.

@bobbingwide
Copy link
Owner Author

Note: This solution will not work for shortcodes which are in other blocks such as the paragraph block.
To cater for these it would be necessary to do_shortcode() within the query loop.

And that probably means overriding render_block_core_post_template()
and calling do_shortcode() on the $block_content returned from

// Render the inner blocks of the Post Template block with `dynamic` set to `false` to prevent calling
		// `render_callback` and ensure that no wrapper markup is included.
		$block_content = (
			new WP_Block(
				$block_instance,
				array(
					'postType' => get_post_type(),
					'postId'   => get_the_ID(),
				)
			)
		)->render( array( 'dynamic' => false ) );
// Note: This function returns quickly if there are no shortcodes in the content.
$block_content = do_shortcode( $block_content );

I hacked Gutenberg to do this and it worked.

This screenshot shows:

  • The green Fields block invokes the shortcode logic directly so it rendered in context
  • The pink shortcode block uses fizzie_render_block_core_shortcode()
  • The orange block uses the hack.

image

@bobbingwide
Copy link
Owner Author

bobbingwide commented Mar 11, 2023

Another way to override the processing for the shortcode block is to hook into the render_block_core/shortcode filter
which is run after the block has been rendered.
The same filter function can be used to filter the paragraph block, and any other block if so required.

/**
 * Filters the rendered shortcode block.
 *
 * @param $content
 * @param $parsed_block
 * @param $block
 * @return mixed|string
 */
function fizzie_render_block_core_shortcode( $content, $parsed_block, $block ) {
    $content = do_shortcode( $content );
    return $content;
}
add_filter( 'render_block_core/shortcode', 'fizzie_render_block_core_shortcode', 10, 3, );
add_filter( 'render_block_core/paragraph', 'fizzie_render_block_core_shortcode', 10, 3, );

Attempting to hook into render_block_core/post-template doesn't work since this is invoked after the whole of the query loop has been rendered. ie It's too late. The context of the different post IDs has been lost.

Using this filter function is my preferred method of ensuring that shortcodes are expanded in the query loop.

  • I no longer need the block rendering override logic, nor the "hack" I implemented in Gutenberg.
  • And the solution should work with/without Gutenberg activated.
  • And I hope that the call to wpautop() that's still run doesn't cause any problems.

@bobbingwide
Copy link
Owner Author

bobbingwide commented Jan 7, 2024

Another way to override the processing for the shortcode block is to hook into the render_block_core/shortcode filter
which is run after the block has been rendered.

This logic works if the template part rendering has been overridden such that do_shortcode() is called after do_blocks().
With WordPress 6.2, it still works in Fizzie, but it doesn't work in my new theme called tt2ai which doesn't override the template part rendering.

tt4ai requires a different workaround to the problem.
I first attempted to create a new template part and include that in the Post Template block.
I was able to create the template part ( named plugin-pricing-fields ) but I couldn't insert the template part into the Post Template block.

Next I saved the same set of blocks as a reusable block.
When used in conjunction with the workaround to expand shortcodes in the shortcode and/or paragraph blocks then it worked as required. Now I need to implement this in wp-secrets.co.uk

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant