0

I'm turning out some subscriber archives and singles (profile pages) in my plugin where I'd also included a 'user-single' template, included via template_include. I'm experimenting however with trimming some of these templates out of my plugin in order to make it use theme templates. I've instead used locate_template( 'single.php' ) to choose the single template from the active theme. I'm not using the global wp_query to turn out my content in this case but the page shows a loop based on the query defaults (ten posts).

What I'm wondering is whether I can completely scrap the default query, replacing it with a wp_user_query into which I can feed the queried user ID. I would like then to filter the_content to customise the output on that user single. I've tried using pre_get_posts and even pushing query vars in via my template_include function ($wp_query->post_type = 'blah') but to no avail as the query always eventually falls back to those default ten posts.

Is there a way for me to use the theme page.php (or single.php) template, intercepting the query to replace it with a wp_user_query or does this have to be a custom template job?

1 Answer 1

0

Is there a way for me to use the theme page.php (or single.php) template, intercepting the query to replace it with a wp_user_query or does this have to be a custom template job?

No, WP pages are either post archives or singular posts, based on a WP_Query. You can create virtual pages based on rewrite rules with parameters and load templates but then either the template is responsible for loading the content, or a normal WP_Query happens using custom parameters from the rewrite rules.

You cannot however swap the post query for a term query or a user query, etc, they are not interchangeable and don't have a common base. Even if the template itself was fine you would run into issues with any plugin that attempted to type hint, and would need to modify significant parts of WordPress plugins and the theme. At an absolute minimum you would need wrappers around WP_User_Query and WP_User to mock the interface of WP_Query and WP_Post, and any code that attempted to use a post ID would just be flat out broken in weird and wonderful ways.

It's much easier to create a custom template and use WP_User_Query directly. If you're looking for a general solution that's portable across themes, none exists. The closest you can get is including your own template in a plugin then trying to load the header.php and footer.php and hoping that's all that's necessary for that theme ( ignoring block themes and site templates ).

and even pushing query vars in via my template_include function ($wp_query->post_type = 'blah') but to no avail as the query always eventually falls back to those default ten posts.

By the time template_include runs it's too late, the main query has already been processed, decided, and the database consulted. Template loading is the very last step and happens after posts are retrieved.

3
  • Thanks, Tom. Makes sense. Since posting this question I hacked the query a bit further by overwriting it completely in template_include (end of the line) with $wp_query = new WP_User_Query($args); which, as you've described, broke all subsequent attempts at interpreting the returned user object as a post object. One further 'hack' that I'm experimenting with however, is simply replacing items in the returned $wp_query->post array with a single 'fake' post made up of my user bits (name in place of title, etc) but by this point it's not a better solution than a custom template. Commented Feb 9, 2022 at 12:24
  • if it's useful, other people have tried doing this in the past to get their custom table stuff etc working in a template, but the results have been.. mixed, it usually involves taking the results and manufacturing some kind of WP_Post analog, but it only works with very basic templates, anything that uses plugins/hooks or tries to use post IDs directly shatters the illusion and leads to brokenness. The biggest issue I struggle to think of a workaround for is pagination. Likewise header calls usually rely on post stuff, e.g. SEO data which trips this up too
    – Tom J Nowell
    Commented Feb 9, 2022 at 12:29
  • I do think though that FSE provides the closest answer, you can provide a template in your plugin and suggest it, perhaps swap out the post query block for a "user query" block then insert your own inner blocks in place of those the theme uses, but it's a fundamentally different approach than what you had in mind and specific to block based templates
    – Tom J Nowell
    Commented Feb 9, 2022 at 12:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.