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

Bug: Can not access current post or postId from shortcodes in Query Loop Post Template #1256

Open
frzsombor opened this issue Jun 25, 2024 · 1 comment
Labels
triage Awaiting review

Comments

@frzsombor
Copy link

frzsombor commented Jun 25, 2024

Description

If I'm using a shortcode in a Query Loop Post Template, the current post ($post or $postId) to which the shortcode belongs is not available in the shortcode itself, only the post id of the page I'm using it on. As with GenerateBlocks we have a whole plugin, we have full control over the blocks and the backend, and even more things. Given this, we should solve this issue with GenerateBlocks.

The issue is, that in the render_block() function we do have the correct postId, but the shortcodes are not executed during block rendering (which takes place before outputting the whole page content), they are only put into the rendered code of a block as they are, and they got executed during outputting the page content, which result in getting wrong/global post ids. (more detailed cause of the problem is at the end of this issue)

This issue has been discussed many times at many places before, but doesn't have an active, open issue in GitHub. I'm creating this issue to track related process here, because currently, only workarounds exist and related discussions were marked as resolved after providing only a workaround for a specific use-case. The issue is also related to WordPress core, these issues are also linked in References.

Possible solutions without verifying that they are adaptable or if they even work:

Steps to reproduce

  1. Create a page
  2. Insert a Query Loop block
  3. In Post Template, use a shortcode that tries to access data of each specific "current" post.

Expected behavior

I expect the shortcode to access $post or $postId of the current post in the loop, that actually renders it

Actual behavior

The $post or $postId is refering to the page in which the shortcode is inserted in.

References:

WordPress/gutenberg#43053
WordPress/gutenberg#35676

https://generatepress.com/forums/topic/guidance-for-how-query-loop-block-treats-ids-for-custom-shortcode/
https://generatepress.com/forums/topic/getting-current-post-in-a-hook-inside-query-loop-in-generateblocks/

https://wordpress.org/support/topic/cant-get-post-data-id-custom-fields-with-shortcode-inside-query-loop-block/
https://wordpress.org/support/topic/custom-field-via-shortcode-inside-query-loop-block/
https://wordpress.org/support/topic/get-postid-of-posts-included-in-query-loop/
https://wordpress.org/support/topic/shortcodes-and-processing-dynamic-data/


Edit, for future reference:

  1. Block render_block() functions
    To understand the issue better, take a look at this code part, which is the main loop in render_block function of Query Loop. If we insert echo 'post id: '.get_the_ID(); right AFTER the first $the_query->the_post(); line of the while loop, we will get the post ids correctly, BUT they will be written right next to each other as the FIRST lines of the page content. This means block render_block() functions and their loops run before actually outputting related page content. However, in the loop we have the correct page ids each loop cycle.
  2. WP_Block->render() functions
    Calling the actual block rendering function in the loop also makes it "render" the block output (without printing it) BEFORE printing the page output. It will still have the correct post, however the actual problem is that, WP doesn't execute shortcodes in it's render function, they are only executed while outputting the full page content (made of rendered blocks). So by the time the shortcode is executed during printing of the whole page, the $post, $postId, the_post(), etc. will refer to the the last post, which is the page.
@frzsombor frzsombor added the triage Awaiting review label Jun 25, 2024
@frzsombor
Copy link
Author

frzsombor commented Jun 26, 2024

I'm happy to share my solution for the issue! I was looking for a solution that doesn't require "hacking" the core of WordPress, is lightweight, universal, easy to use, configurable, and relies solely on native approaches while ensuring everything works as originally intended where this solution isn't needed. The solution is also versatile enough that it works with both the original WordPress loop and the GenerateBlocks loop, regardless of which one is used.

I suggest integrating a slightly modified version into GenerateBlocks (which simply ensures that, in addition to the basic text-type blocks, it is also enabled for GenerateBlocks Headings) until there is progress from the WordPress side. This could be an additional feature in GenerateBlocks that makes its use even more beneficial.

All details can be found here:
https://gist.github.com/frzsombor/c53446050ee0bb5017e29b9afb039309


image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage Awaiting review
Projects
None yet
Development

No branches or pull requests

1 participant