While wordpress is doing the main loop, how does it determine which post belongs to the current page?
<?php while ( have_posts() ) : the_post(); ?>
<?php
get_template_part( 'template-parts/content', get_post_format() );
?>
<?php endwhile; ?>
In the above example, how does WordPress determine which post will be looped over?
Will the loop go through all the posts?
The main query runs for every page request. The main query makes use of the WP_Query class to fetch posts according to the parameters set via the URL structure of the page. WP_Query works exactly the same in the main query as it is with a custom query, the only diffirence here is the way how paramteres are passed. For the main query, the parameters passed is determined by URL, while for a custom query the parameters are manually set by the user
In short, this is what happens on every single page request made by the browser
The URL is checked and the current permalink structure is checked against the saved structure in the db. If any other permalink structure is in place in stead of the default permalink structure, the current permalink structure is checked against the default structure, and the URL is matched
A set of parameters with values are generated against the URL and permalink structure. Remember, the URL structure is a set of $_GET variables, this $_GET variables is a key/value pair that represents a parameter/value pair in WP_Query. The blank parameters that are still left (there are plenty) after the others have been filled from the URL are filled with default values. Here for instance is the posts per page which is set by get_option( 'posts_per_page' ) which represents the amount of posts set in the back end reading settings.
In short, so far, what the above says is, if you request a category page of your site, the URL is checked and is determined to be a category page. The category is identified and passed to the query as a key/value pair, which will at the end determine that the current page must show posts from this particular category
From all these parameters and their values, the SQL query is build accordingly which will query the database for posts according to the conditions set in the SQL query. The posts are returned and stored as objects
These post objects together with other important information is stored in one big object, the main query object, which is stored in the $wp_query global variable
Up till now, the loop has done absolutely nothing. All of the above happens whether or not you have a loop on the page or not. The loop only does two things
Access the main query object and loops through the post objects. How these objects are send to screen is determined by how the HTML markup, PHP and CSS is constructed inside the loop. The loop uses a while() loop which checks after the completion of one post if there is another post to display. If there is, the while() continues to execute, and it does so till no more posts are left and then kills execution. This is basic PHP, so be sure to check how a while() loop works
The second function the loop does is setting value of the $post global. This is done by the the_post() call inside the loop. On every iteration, the $post global is set to the current post being looped though
This is just a basic overview. Each process is huge and quite difficult to understand, and therefor, one can never address the whole complete process in detail. I hope this helps
I am pretty sure the short answer is, "it's in the query for the current page". The codex discusses the loop and understanding its use:
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. Any HTML or PHP code in the Loop will be processed on each post.
The Loop
Well I think show the post with this codes
<?php
get_template_part( 'loop', 'index' );
?>
u can use wp_query Object
<?php
// The Query
$args = array (
'post_type' => 'post',
'post_status' => 'publish',
);
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
echo '<ul>';
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo '<li>' . get_the_title() . '</li>';
}
echo '</ul>';
} else {
// no posts found
}
/* Restore original Post Data */
wp_reset_postdata();
?>
Other Code is here
<?php
if ( have_posts() ) {
while ( have_posts() ) {
the_title();
the_content();
}
}
?>
Related
I have a problem with a website that has been working for YEARS. Suddenly something has changed (no plugins were added).
Basically, I have a "post" page that displays 1 post at the top and then a couple of posts later down the page. The problem I have is that in these secondary posts, after establishing a new wp_query object, the "the_content()" and even trying to manually dump "$second_loop_post->post_content" into an apply_filters function returns nothing. The "the_content()" returns NULL. The kicker? the_title() and every other call works just fine for pulling out information. I can even pull out the unformatted info. But there seems to be something wrong with basic "apply_filters" which is also affecting "the_content()".
See below. Basically, when I load the page and try to do a custom query (even without displaying anything beforehand), it won't work. If I remove the custom $wp_query below however, it will spit out the information for that post page. The problem is I need the second and third queries I do to also display this content information .... and nothing. I'm going crazy. Help please.
global $wp_query;
$original_query = $wp_query;
$wp_query = null;
$wp_query = new WP_Query( array(
'posts_per_page' => 1
) );
if (have_posts()):
while (have_posts() ) : the_post();
the_title();
the_content();
endwhile;
endif;
I am trying to deal with two get_post functions, in single.php the first get_post function is the post from the wordpress, But after that I called get_post function to other post also to use both of them in the same page but after I call the first get_post ( the main post ) I get the only second data and cant reach the first data.
My code called to the second function ( The first is from wordpress post):
$main_post = get_field('main_post');
$main_p = get_post($main_post->ID);
Then I am trying to use the variable $post OR the_title() OR any other functions to get the first post and it always returning the info of the $main_p post
for example
get_the_title( get_post()->ID )
returns the $main_p post id and not the main post of the single.php
any soulutions ?
I may be wrong, but it seems to me that you are trying to post a different post format with normal post format?
I, myself use get_post_format() so it can be styled differently or have different options.
in single.php I use
<!-- checking if there are any blogposts to be shown using have_posts check which is a wordpress function-->
<?php if(have_posts()) : ?>
<?php while(have_posts()) : the_post(); ?> <!-- the correct syntax for while loop in wordpress to show all the blogposts -->
<?php get_template_part('content', get_post_format()); ?>
<?php endwhile; ?>
<?php else : //else stament if there aren't any posts (put inside if before endif)?>
<p><?php __('No Posts Found'); ?></p>
<?php endif; ?> <!-- stop checking for blog posts-->
</div><!-- /.blog-main -->
Inside functions.php I activated the post-formats inside wp_theme_setup() function
add_theme_support('post-formats', array('aside', 'gallery'));
In this case i activated the gallery and aside posts
That way I have 2 different post types on one page
like this
image from my theme blog page
Here is also a video tutorial on post formats from Traversy media
https://www.youtube.com/watch?v=CRa7eiqyiCM&list=PLc5p9nvpdwBlrNU0hr1f0kXPRkh0aGo1Q&index=7
The key reason why your post values are being overwritten, the additional get_post() declarations are overriding the default query. Now, the code in your pastebin is a pretty massive dog's breakfast, so a direct solution is a rather large undertaking (e.g. the indentation is all over the place, the code snippets are less than ideal regarding their readability, etc...). However, I can point you in the right direction for the solution.
When I pull content from another page on my WordPress sites, I avoid using get_post() in favour of declaring a fresh new WP_Query() (that's just my preference), following it up with a wp_reset_postdata() declaration.
Here's an example of multiple queries on a single template in the WordPress codex:
https://codex.wordpress.org/Class_Reference/WP_Query#Multiple_Loops
The key here is the wp_reset_postdata(). I'd recommend looking into it's purpose. It'll save you a lot of grief:
https://codex.wordpress.org/Function_Reference/wp_reset_postdata
i'm seeing some strange behaviour I cannot explain inside a category-based template loop.
i have a custom query filter for the category template, preselecting a couple of custom post types to query for:
add_filter( 'pre_get_posts', 'cust_posts_collection' );
function cust_posts_collection( $query ) {
if ( (is_category() && $query->is_main_query()) )
$query->set( 'post_type', array( 'cust_post_type_1', 'cust_post_type1' ) );
return $query;
}
this results in a proper $wp_query object, containing among others an array of posts. let's say for a given category x there are 4 posts. when i var_dump $wp_query i can verify
["posts"]=>&array(4)
and i can see all the posts and their data in the dump.
however, when i loop then over that object:
<?php if ( $wp_query->have_posts() ) while ( $wp_query->have_posts() ) : $wp_query->the_post();
var_dump($post);
endwhile; ?>
all i see is two posts.
how is this possible?
are there any configuration defaults on the loop functions that i am missing?
I was able to solve the bug:
it turns out that there was another loop in the header partial, prior to the loop exposing the bug.
the first loop had a break statement right after an if conditional - the idea: find the first occurrence of a certain custom post type and then break out of the loop.
the problem: this break did not properly reset a global post index variable or something along those lines. the next loop then got a wrong state of the index, causing it to jump as many initial posts as had been looped over in the previous loop.
adding rewind_posts() just before the break fixed this for me.
I am working on a WordPress theme. I use a plugin to display pictures on a page (for each post 1 picture), Whenever one of this pictures is clicked the following code registers this and opens a lightbox with the content of the post in it:
<?php
if($_REQUEST['popup']!=''){
$postObj = get_post( $_REQUEST['pid'] );
echo '<div class="ostContent">'.$postObj->post_content.'</div>';
exit;
?>
This all works fine.
Now the problem is that all content get displayed nicely. but for some reason shortcodes don't work. and also when I use a widget in post plugin to display a widget in the post, it doesn't get displayed.
First I tought I needed to enable shortcodes. So I changed this:
echo '<div class="ostContent">'.$postObj->post_content.'</div>';
with this:
echo '<div class="ostContent">'.do_shortcode( $postObj->post_content ).'</div>';
But still nothing. So now I have no idea what to change to make the lightbox show widgets
Hope anyone knows the solution!
EDIT: when I open the post outside the lightbox (by just going to the single page) the shortcode get used like it should be. so somehow the code above don't recognize the shortcode or...
According to a sample here: http://codex.wordpress.org/Function_Reference/do_shortcode
It looks like you need to change: echo '<div class="ostContent">'.do_shortcode( $postObj->post_content ).'</div>';
to:
echo '<div class="ostContent">'.do_shortcode([shortcode_in_brackets]).'</div>';
This should actually display the code. I am assuming that you have defined the actual text in the widget in which the shortcode applies.
Otherwise in the way you currently do it the PHP fires before the post_content even has a value.
I think I understand your problem.
The following should work, assuming the posts in question have a post_type of post:
<?php
// Check for existence of 'popup' & 'pid' query vars
if ( $_REQUEST['popup'] && $_REQUEST['pid'] ) {
// Select single post by ID (using value of the 'pid' query var)
$query = new WP_Query( array ( 'p' => $_REQUEST['pid'] ) );
// Check that the query has returned something
if ($query->have_posts()) {
/* Loop through query until we run out of posts
(should only happen once in this case!) */
while ($query->have_posts()) {
// Setup post, so we can use the_content() and stuff
the_post();
echo '<div class="ostContent">';
/* The part we've been waiting for! the_content() will
display your post content as expected */
the_content();
echo '</div>';
}
}
}
?>
WP_Query is the way to go the majority of the time when needing to retrieve posts: http://codex.wordpress.org/Class_Reference/WP_Query
Your code was retrieving and displaying data almost directly from the WordPress posts table, giving WordPress no chance to apply any of its internal actions and filters (e.g. automatic paragraphs from double line breaks, shortcode execution).
I have a problem Im trying to solve and not having much luck, Iv tried google/stackoverflow etc, but all I find in general 'random post' type answers
here's the issue:
I am getting my posts using a pretty standard loop
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php $cat = get_the_category();
if(strtolower($cat[0]->name) != 'hidden'){
?>
I then display all the post data etc, etc.
I have a custom post type, with an option in the back end to limit the number of these custom posts that can be shown on the homepage
get_option('max_amount')
What I want to do is mix some of the custom posts (custom post type) in with the posts from the loop, not exceeding the 'max_amount' BUT I dont want them next to each other, I need them mixed in.
Hope that all makes sense and someone can help or point me in the right direction
Thanks
If you add the posts to and array you could then use shuffle($posts) to randomise the post. Then use $posts = array_slice($posts, 0, get_option('max_amount') to ensure you don't exceed the max amount.