Should I place wp_reset_postdata(); after endwhile; or endif; ? - php

I have spent some time reading through the WordPress Codex, as well as various themes, and can see that some developers insert <?php wp_reset_postdata(); ?> after the endif; in a Blog Loop whilst others insert the code between the endwhile; and endif; of a Blog Loop. I have tried both locations but have yet to see a difference. Is there a correct location?

This function supposed to reset the secondery query that you run.. the function the_postis letting you to use all the functions that you can run in the loop like the_title() the_content and so on..
So you reset the the_post function and after the endwhile; you can reset it already. and use your main query inside the if statment too if you like.
<?php
// this is the main query check if there is posts
if ( have_posts() ) :
// loop the main query post and run the_post() function on each post that you can use the function the_title() and so on..
while ( have_posts() ) : the_post();
the_title(); // title of the main query
// the is second query
$args = array( 'posts_per_page' => 3 );
$the_query = new WP_Query( $args );
// check if there is a posts in the second query
if ( $the_query->have_posts() ) :
// run the_post on the second query now you can use the functions..
while ( $the_query->have_posts() ) : $the_query->the_post();
the_title();
the_excerpt();
endwhile;
// reset the second query
wp_reset_postdata();
/* here we can use the main query function already if we want..
its in case that you want to do something only if the second query have posts.
You can run here third query too and so on...
*/
the_title(); // title of the main query for example
endif;
endwhile;
endif;
?>

wp_reset_postdata() is only required if you have a secondary loop (you're running additional queries on a page). The purpose of the function is to restore the global post variable back to the current post in the main query.
Example:
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
OUTPUT MAIN POSTS HERE
<?php endwhile; endif; ?>
In the code above I'm simply using the main loop to display posts. There's no reason to include wp_reset_postdata(). The global post variable is exactly what it's supposed to be.
If somewhere else on the page I decide to add a secondary loop, then I'll need wp_reset_postdata().
// This query is just an example. It works but isn't particularly useful.
$secondary_query = new WP_Query( array(
'post_type' => 'page'
) );
if ( $secondary_query->have_posts() ) :
// Separating if and while to make answer clearer.
while ( $secondary_query->have_posts() ) : $secondary_query->the_post();
// OUTPUT MORE STUFF HERE.
endwhile;
wp_reset_postdata();
endif;
To answer your original question: it usually comes after endwhile and before endif. It's the call to the_post() which actually changes the global post variable. If there are no posts then the post variable remain the same and there's no reason to use the reset function.

Related

Display Wordpress posts in Chronological (Ascending) Order

By default Wordpress shows all posts in reverse chronological order (with the newest post first).
I would like to display all of my wordpress posts in chronological order (with the oldest posts shown first).
I am trying to use a custom loop query to do this, however I cannot get it to work. What am I missing here?
<?php query_posts(array('orderby'=>'date','order'=>'ASC'));
if ( have_posts() ) :
while ( have_posts() ) : the_post(); ?>
<div class="postTitle"><?php the_title(); ?></div>
<div class="postContent"><?php the_content(); ?></div>
<?php endwhile; endif;
wp_reset_query();
?>
I thought this would be quite simple, although everything I have found to try I also cannot make work. thanks!
Using custom loop:
If you are creating a custom loop you might want to use WP_Query instead.
<?php
$the_query = new WP_Query([
'order'=>'ASC'
]);
// The Loop
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) :
?>
<div class="postTitle"><?php the_title(); ?></div>
<div class="postContent"><?php the_content(); ?></div>
<?php
endwhile;
/* Restore original Post Data */
wp_reset_postdata();
?>
<?php else: ?>
// no posts found
<?php endif; ?>
Using filters
Or another method is to alter the main loop using filters in your functions.php file.
function alter_order_of_posts( $query ) {
if ( $query->is_main_query() ) {
$query->set( 'order', 'ASC' );
}
}
add_action( 'pre_get_posts', 'alter_order_of_posts' );
I suggest the filter path to avoid changing a lot of your current template.

Can anybody explain "The Loop" of wordpress?

Im forced to work with wordpress, and if you work with it, you probably know what i mean:
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
Its working, no question. But i do not understand what this actually means. Its not a ternary operator nor anything else i know. Ive never seen a statement like this in any php-projects ive worked on. So i got several questions:
What is this line exactly doing? I know that it gets all posts, iterates over them and ... what is this the_post() doing? And what are these doubledots doing?
Is this Wordpress-Only or could it be used somwhere else too?
Where is the current post stored?
Ive already googled it, but there are no information regarding my problem, noone seems to be interested in how wordpress works. I am, but i do not get it. If somebody got an explanation for me, it would be great.
<?php define('WP_USE_THEMES', false); get_header(); ?>
The loop starts here:
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
and ends here:
<?php endwhile; else: ?>
<p><?php _e('Sorry, no posts matched your criteria.'); ?></p>
<?php endif; ?>
This is using PHP's alternative syntax for control structures, and could also be expressed as:
<?php
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
//
// Post Content here
//
} // end while
} // end if
?>
the post()
This function does not accept any parameters.
Return Values
This function does not return any values.
<?php
while ( have_posts() ) : the_post();
echo '<h2>';
the_title();
echo '</h2>';
the_content();
endwhile;
?>
have_posts()
Parameters
This function does not accept any parameters.
Return Values
(boolean)
True on success, false on failure.
Examples
The following example can be used to determine if any posts exist, and if they do, loop through them.
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
// Your loop code
endwhile;
else :
echo wpautop( 'Sorry, no posts were found' );
endif;
?>
Note
Calling this function within the loop will cause an infinite loop. For example, see the following code:
<?php
while ( have_posts() ): the_post();
// Display post
if ( have_posts() ): // If this is the last post, the loop will start over
// Do something if this isn't the last post
endif;
endwhile;
?>
If you want to check if there are more posts in the current loop without this unfortunate side effect, you can use this function.
function more_posts() {
global $wp_query;
return $wp_query->current_post + 1 < $wp_query->post_count;
}
1. What is LOOP
The Loop is PHP code used by WordPress to display posts. Using The Loop, WordPress processes each post to be displayed on the current page, and formats it according to how it matches specified criteria within The Loop tags.
It will fetch data related to specific page
:(colon) is used to tell condition/loop starts from here. You can replace it with { }(bracket quotes)
<?php
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
//
// Post Content here
//
} // end while
} // end if
?>
2. Is this Wordpress-Only or could it be used somwhere else too?
yes of course you can use it.
You can access full wordpress functionality by including one core file with name of "wp-blog-header.php" that is located on root of wordpress directory.
<?php
/* Short and sweet */
define('WP_USE_THEMES', false);
require('./wp-blog-header.php');
?>
Include this file in the top of your external file, you can access wordpress database, wordpress function , wordpress hooks too.
3. Where is the current post stored?
11 default tables are existed in wordpress database. You can see wp_posts table in database. all posts are store in this table.
suppose, if your are creating meta tag in your post, it will store in wp_postmeta
It's just an alternative syntax for:
if ( have_posts() ) { //open if
while ( have_posts() ) { //start while loop
the_post(); //call a function
See http://php.net/manual/en/control-structures.alternative-syntax.php
It's not wordpress specific and can be used in any php code.
To whom it may concern.
What is WordPress Loop?
When we save data inside WordPress(posts, pages, almost everything) data gets saved as a row inside our database fx. MySQL.
WordPress dynamically query the database and finds which row corresponds to the page you are on, and pulls that data then displays it in that section.
As this is a dynamic query and executed in a repeated manner, it is called a WordPress Loop
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
What are these doubledots doing? condition/loop starts from here :(colon) and is a ternary operators.
I think rest of the questions has been answered by others.

How to get wordpress main query posts as an array

I need to get the main query posts as an array. Example, in common tag page(tag.php), I need to get all the posts as an array ( like get_posts() do) and display it using some multiple loops instead of using default wordpress loop as shown under
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php endwhile; else: ?>
<p><?php _e('Sorry, no posts matched your criteria.'); ?></p>
<?php endif; ?>
$posts is the variable you're looking for it. It is the equivalent of get_posts results for the main query. It's in the global namespace, so in order to access it somewhere else you'll need to use the keyword global.
global $posts;
foreach( $posts as $a_post ) {
echo $a_post->post_title;
}

wp_query not working

I've decided to start using wp_query instead of query_posts, on my home page I want to call the content from a particular page inside a div. Just wondering what am I missing here as nothing is appearing and I do have a page with content with an ID of 140. Im still quite new to this thanks!
<div class="home-info" >
<?php
if (have_posts() ) :
$the_query = new WP_Query( 'paged=140' );
while ($the_query->have_posts() ) : $the_query->the_post();
echo the_content();
endwhile;
wp_reset_postdata();
endif;
?>
</div>
You've used the wrong argument in WP_Query, it should be page_id rather than paged. Here's the reference from the Codex;
http://codex.wordpress.org/Class_Reference/WP_Query#Post_.26_Page_Parameters

WordPress - restore original WP_Query

I've got post type called "Portfolio" and single-portfolio.php file to handle it (it's WordPress). When I use there something like that it works like expected:
$post_id = $post->ID; //returns ID of current portfolio post. Good!
BUT when I post short query like this in the middle:
$post_id = $post->ID; //returns ID of current portfolio post. Good!
wp_reset_query();
query_posts('posts_per_page=4');
if ( have_posts() ) : while ( have_posts() ) : the_post();
the_id(); //returns ID of standard blog post
endwhile;
endif;
wp_reset_query();
$post_id = $post->ID; //returns ID of last BLOG post. Wrong!
I'm only concerned about $post_id variable in above example. I want it to always return correct ID of current PORTFOLIO post and not be dependent on other queries. How do I achieve that?
I believe wp_reset_postdata() will give you the result you are looking for.
$the_query = new WP_Query( 'posts_per_page=4' );
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
// output
endwhile;
endif;
wp_reset_postdata();
I should note that there is another approach which I have documented in another question asking about what is the difference and when each should be used.
The wp_reset_query function does reset the global $post variable as well, but only based on the global $wp_query variable. That still is modified, probably due to one of the little flaws in Wordpress. In your case I'd say a simple WP_Query::rewind_posts() should do it:
wp_reset_query();
$wp_query->rewind_posts();
$post_id = $post->ID;
Also you should consider to create a second loop, not overwrite the first one.
See as well:
Wordpress wp_reset_query() does not go back to last query?

Categories