Set wordpress query before template - wordpress

I have a business goal forcing me to try to change the global wordpress query after the URL has been determined, but before the templates start outputting variables in the context of the original post. I need to be able to use a plugin to check some meta values on the original post, and then change the query to represent another post object to display different data without changing the url.
I've tried using setup_postdata() what seems like everywhere.
(tried including wp_reset_query();)
global $post;
$post = get_post(145, OBJECT );
setup_postdata($post);
However, the template is still outputting the original query.
I'm open to other solutions. Thanks in advance.

add_action('wp_loaded', function(){
query_posts(array('p'=>145,'post_type' =>'any'));
});
This worked out fine. It can be added just about anywhere. However, it messes up page templates, and displays pages as if they're single.php!!! If I can get around that, then I'll be in good shape. Help?
EDIT: Got it working. I have to check and use p for posts, and page_id for pages. So long as those are set, the templates will follow correctly. Otherwise it was trying to apply the standard post template to pages.

Related

No other way to put this: How do I use The Loop?

I apologise for this post being so long. The REASON for me asking such a stupid question as the topic suggests is BECAUSE there is just so many different things going wrong that I need to provide details of WHY I am asking this question.
Please bear with me...
I am busy creating a custom theme for my personal use have a LOT of slug-based pages and I use WP_query a lot(!) for many things from a custom news ticker to procedurally generating my navbar to mention but a few.
I was under the impression that creating a custom WP_Query means the content inside the results will not interfere with the operation of the main Loop and yet, I get very strange behaviour...
All my custom slug-based pages always work perfectly fine but when I use this in my navagation.php template part:
$query = new WP_Query($args);
if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post();
//do my stuff here
endwhile; endif;
...this results in pages and posts loading just fine during the Loop but when I get to the product I am trying to view it always shows the same product no matter what link I follow. Eventually I added this to the product page:
if (have_posts()) {
the_post();
rewind_posts();
}
...and that made the products load up just fine. Yeay! No idea WHY I have to do it but it works. Strangely enough, though, in the template, just before it loads the template part that does the product layout, I print the name of the post currently in the global $post and then watch as it prints the wrong name above the right product after starting the Loop. (!?)
So then I find out about get_posts() and I like the fact that it gives me an array rather than an object that contains an array and so I swap over to using get_posts() in my navigation.php header template part and now my header section still works perfectly and my products display perfectly... but all posts and pages now show the same content. All posts and pages now show the same WooCommerce product. (!?) What's more confusing is that I do 3 WP_Query calls in navigation.php and the Loop in my posts and pages all show the first entry from the FIRST query, not the last...
After much struggling I decided it wasn't worth the aggravation so I swapped back to using WP_Query. Now things are all messed up in ways I can't even begin to understand... Now my posts and pages work just fine (so does my custom menu) but my products now all show the same product while in the loop. I tried doing this:
global $post;
$current = $post;
//do my query and loop over it
$post = $current;
Somehow that code turns the $post (which is just a pointer into the array) into an array itself (or something) because the product template now first displays the same product on every page I go to and then it displays the $post product it was supposed to directly below it. If I set $post to null directly after I set $current then setting $post back to $current afterwards results in only the wrong page showing up.
Somehow I managed to get it to stop showing the wrong product and now, instead, only my slug-based pages work because anything that uses the Loop (post, page and product) just tells me this:
Fatal error: Uncaught Error: Cannot use object of type WP_Query as array in D:\xampp\wordpress\htdocs\wp-includes\class-wp-query.php:3071 Stack trace: #0 D:\xampp\wordpress\htdocs\wp-includes\class-wp-query.php(3099): WP_Query->next_post() #1 D:\xampp\wordpress\htdocs\wp-includes\query.php(805): WP_Query->the_post()
..and tracking the stack trace to where that occurs seems to indicate that (apparently) I am trying to use a WP_query as an array when I say this during the Loop:
if (have_posts()) : while (have_posts()) : the_post()
How is THAT code wrong? It's straight from the manual! :O
According to the Codex, even though get_posts() also uses WP_Query it allows you to have multiple Loops and it says that you should use the restore_post_data() (I think) IF you updated the main Loop contents. But I am NOT trying to modify the main Loop at all. I want to do a query, have the results in a variable, run over that result and then discard the variable before going into the Loop and showing the page content as normal. I want my queries to run independently of the Loop and NOT in any way interfere with the operation of the Loop at all.
So:
why the heck does my custom WP_Query calls interfere with that I am seeing in the Loop and
why the heck do I get the error about trying to pass a WP_Query object as an array when calling the default, vanilla Loop
why do my products display correctly but my posts and pages do not
or why does my post and pages show correctly while my products show two different products
How the heck can my fully functional site get THIS broken just by going from $posts = get_posts($args) to $query = new WP_Query($args) ???? In a separate job completely outside the Loop, no less!
It makes absolutely no sense and since it makes no sense I have no idea where to start when trying to implement a fix. So what am I not seeing here? rewinding the posts, restoring the post data... nothing helps. I am completely dumbfounded.
Am I not using the Loop correctly? All I want to do is this:
Load a page that does a custom WP_query and displays the content
Load the template part that performs the Loop (i.e. single-product)
Display the template part that page loads (i.e. content-single-product) and have it be the right content
It shouldn't be this hard, should it?
Such a simple little thing to cause such a massive amount of grief... :(
Inside my navigation template part when I made the switch back from get_posts() to WP_Query I stored one query in $posts and the other in $query. Seems $posts is a reserved variable in WordPress because the moment I changed $posts to $query also everything worked 100% perfectly again!
I was aware of $post but not $posts. Now I know. Special thanks to #zipkundan for pointing me towards wp_reset_postdata(). That page taught me that custom queries DO in fact affect the global Loop (News to me!) and showed how to work around it.
So basically, the problem with my posts not showing what they were supposed to was due to me not calling wp_reset_postdata() after running through my custom loop and the reason for all the inexplicable weird page anomalies was due to me saving my custom query to a reserved variable name.
Mystery solved.

Is it necessary to reset the query after using get_posts()?

I have placed following code for retrieving 3 posts on my homepage, and the code is working fine, now I just want to know that Is that necessary to reset the query using "wp_reset_postdata()" after using get_posts or there is no need to wp_reset_postdata() function as the following query is working fine..
Click here
If you haven't used setup_postdata (explicitly or implicitly via $myWpQuery->the_post()) , you won't need to reset the post data. get_posts() itself doesn't change the post context, so get_the_ID() etc will work the same before and after using get_posts().
It is standard method to reset query. However, you can skip it; it is not necessary if you wont have any other queries to the DB for posts on the same template page.

Appending query parameter to Woocommerce category URL

I'm trying to force display the list view in my Woocommerce store but I can't seem to get it working.
The theme has support for list view and you can force it by appending "?product_view=list" so a category URL becomes:
http://subliminalscience.com/product-category/icbch-hypnosis-certification/?product_view=list
Instead of the default one:
http://subliminalscience.com/product-category/icbch-hypnosis-certification/
I added this Rewrite Rule to my htaccess but it doesnt:
RewriteRule ^product-category(.*)$ http://subliminalscience.com/product-category$1?product_view=list
It seems Wordpress ignores this Rewrite rule. Any ideas?
I'm surprised this answer stands as the only one.
Making changes in .htaccess to force this sort of behaviour seems really unnecessary and obviously isn't useful for others trying to solve this issue, especially those users on nginx servers or on shared hosting without .htaccess access.
You should try to fix this in PHP using an action.
Looking at your question, I can tell that theme you have is checking for GET data in the URL bar, which is the ?key1=value1&key2=value2 part of an URL. GET is an HTTP method that you can read about here if you want to learn more.
You can actually set GET data in PHP, and you can safely put this into your functions.php file.
You will want to create a function that simply checks the current page, and if it's a product category page sets the GET data.
At the bottom of your functions.php, you'd want to add something like this:
<?php
//Force all category pages to list view.
add_action('woocommerce_before_main_content','force_category_list_view', 5);
function force_category_list_view(){
if(is_product_category()){
$_GET['product_view'] = 'list';
}
};
?>
I actually can't test this, but I think it'd work. Essentially, in the woocommerce template archive-product.php, the first action that runs is 'woocommerce_before_main_content'. What we're doing is calling our function, which checks the page is indeed a product category. If it is, it sets the GET variable as list, which is exactly what the URL is telling the page to do already.
Mainly this is just a better practise than altering your .htaccess, but someone determined could also override that GET data by changing the URL to read ?product_view=list&product_view=xyz I can't imagine this would be an issue in this instance, but in other instances it might be.

How can I display WPAlchemy post meta in my custom wordpress template?

I am using the WPAlchemy class to create a meta box for my custom post type which includes image upload fields. The setup works and I can add image and save the images url for each post. I setup everything as shown here: http://www.farinspace.com/wpalchemy-metabox/#installsetup
How do I now display the saved image meta url on my page? Ideally I would like to be able to display as an image on the page by adding the image's url to image src so it displays the image not the link. However I would be happy to just display the url on the page to start to make sure it's present. But I am really stuck knowing how to echo or print the info to the page. I have tried following some of their examples but nothing seems to be working and I sometimes get php errors saying:
Fatal error: Call to a member function the_name() on a non-object in C:\
Any help appreciated. I thought it would be easier than it is, like the_meta() or something similar but it's not clear what to add to get the info showing up on page.
Cheers
Best things to do is use:
global $custom_mb;
$meta = $custom_mb->the_meta([ID_IS_OPTIONAL]);
$meta will be an array of all your stored values for the given post, loop through it as you normally would loop an array

Is there way to check if a post is attached to a particular taxonomy?

I want to create a condition whereby if a post is attached to a particular taxonomy then some additional code is executed on a modified single.php but I can't find a way to directly check for the taxonomy.
I thought "is_tax" might do the job but it seems that this tag is only effective for archive pages, which I assume means a page that is generated from a template using the taxonomy name.
Is there a direct way to read the taxonomy from a single post so that I can do something similar to:
if (is_tax('chapter')) {additional code}
Thanks
I worked out one solution for this as follows:
$terms = get_the_terms( $post->ID , 'chapter');
if($terms) { *additional code to be added to the template* }
If any terms in the taxonomy 'chapter' are returned the additional code is added to the template otherwise the additional code is omitted.
I don't know if this needs any additional error checking but the code as shown works by including code on the appropriate posts and omitting it where its not required.
Any suggestions on improvements would be welcome.

Resources