I have a foreach loop which is only returning the title of the latest post. For example, I have the post test as the latest post in products and in the loop defined below, when doing var_dump, it only dumps the title for the latest post called "test".
Why is this?
Approach:
<?php
$args = array(
'post_type' => 'products',
'post_parent' => 0,
'posts_per_page' => 15,
);
$products = get_posts( $args );
if ($products){
foreach ($products as $product) : setup_postdata( $product );
var_dump(get_the_title());
endforeach;
wp_reset_postdata();
}
?>
foreach ($products as &$product) : setup_postdata( $product );
Please try this in your foreach loop.
Use this one
if ($products){
foreach ($products as $product) : setup_postdata( $product );
echo get_the_title($product->ID));
// or echo $product->post_title;
endforeach;
wp_reset_postdata();
}
It's strange but when you're wanting to use template tags along with setup_postdata() you need to use the global $post variable. setup_postdata() doesn't actually set that variable it sets some related global variables and runs the the_post action. You can see what happens here
To do what you want to do with out passing ids etc for every template function call you would need to setup your loop like this.
global $post;
foreach ( $products as $post ) {
setup_postdata( $post );
// Your code here.
}
wp_reset_postdata();// Reset the global $post variable and re-setup postdata.
Related
My posts get ordered by date which is picked by an advanced custom field datepicker. I want to use the regular Wordpress function references [the_title(), etc …] and the post related custom field's.
Right now the output of every loop is the the same. I read setup_postdata() can solve this issue and enable the use of the regular function references. I tried to apply it, but the output keeps being always the same. Thanks
<?php
global $posts;
$posts = get_posts(array(
'post_type' => 'post',
'meta_key' => 'release_date',
'orderby' => 'meta_value_num',
'order' => 'DESC'
));
$group_posts = array();
if( $posts ) {
foreach( $posts as $post ) {
$date = get_field('release_date', $post->ID, false);
$date = new DateTime($date);
$year = $date->format('Y');
$month = $date->format('F');
$group_posts[$year][$month][] = array($post, $date);
}
}
foreach ($group_posts as $yearKey => $years) {
foreach ($years as $monthKey => $months) {
echo '<li class="time">' . $monthKey . ' ' . $yearKey . '</li>';
foreach ($months as $postKey => $posts) {
setup_postdata($posts); ?>
<li class="item clearfix">
<!-- Wordpress Functions -->
<?php the_title();?>
<?php the_permalink();?>
<!-- Advanced Custom Fields -->
<?php the_field('blabla')?>
</li>
<?php
}
}
} wp_reset_postdata();
?>
You just need to add a line $post = $current_post; just before calling setup_postdata( $post ). See my example below to have a clear idea:
$posts = get_posts(array(.......));
// Call global $post variable
global $post;
// Loop through sorted posts and display using template tags
foreach( $posts as $current_post ) :
//the below line is what you missed!
$post = $current_post; // Set $post global variable to the current post object
setup_postdata( $post ); // Set up "environment" for template tags
// Use template tags normally
the_title();
the_post_thumbnail( 'featured-image-tiny' );
the_excerpt();
endforeach;
wp_reset_postdata();
For details please see this comment posted in the WP-Codex;
I am using Advanced Custom Fields with Wordpress.
I have a custom post type called VIDEOS which has two fields - video_link and video_artist.
I can call and output the video_link field, but I cannot seem to display the 'video_artist' field using the code below...
<?php
$posts = get_posts(array(
'post_type' => 'videos',
'posts_per_page' => -1
)
));
if( $posts ): ?>
<?php foreach( $posts as $post ):
setup_postdata( $post )
?>
<?php echo wp_oembed_get( get_field( 'video_link' ) ); ?>
<?php the_title(); ?>
<?php the_field('video_artist'); ?>
</div>
<?php endforeach; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>
In fact, this line...
<?php the_field('video_artist'); ?>
...breaks the site and displays nothing at all after it appears. No html of any kind.
It's more or less the same code as your, just tested, and it works fine
As #admcfadn said, your are note in a wordpress loop, so you need to add the post id as a parameter of the_field
$posts = get_posts(array(
'post_type' => 'videos',
'posts_per_page' => -1
));
if( $posts ):
foreach( $posts as $post ):
setup_postdata( $post );
the_title();
the_field('video_link', $post->ID);
the_field('video_artist', $post->ID);
endforeach;
wp_reset_postdata();
endif;
If you like to use the loop without arg in the_field that will look like that:
$options = array(
'post_type' => 'videos',
'posts_per_page' => -1
);
$query = new WP_Query( $options );
if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post();
the_title();
the_field('video_link');
the_field('video_artist');
endwhile; endif;
ps: you don't need to use <?php ?> on each line
$post->the_field('video_artist');
you're using get_posts, not wp_query, so you might need to refer to the variables via $post.
&/or troubleshoot it with the following:
the_field('video_artist', $post->ID);
might get if for you.
Or...
$baz = get_field( 'video_artist' ); echo $baz;
Also, looks like you're missing a semi-colon after setup_postdata( $post ) and have an extra closing parentheses after get_posts
I'm actually using this short snippet of code to display some content on my website.
<?php
global $post;
$myposts = get_posts('numberposts=3');
foreach($myposts as $post) :?>
content
<? php endforeach; ?>
And I wanted to know if there was a way to incorporate the offset function of wp into it.
Yes you can
<?php
global $post;
$args = array(
'numberposts' => 3,
'offset' => 0,
);
$myposts = get_posts($args);
foreach($myposts as $post) : setup_postdata( $post ); ?>
content
<?php endforeach; ?>
Just look at documentation.
I try to push each data from the Wordpress loop into array:
<?php
$array = array();
$args = -1;
$posts = get_posts($args);
foreach ($posts as $post){
array_push( $array, array(
"title" => get_the_title(),
//capire perchè non stampa il contenuto
"cont" => get_the_content()
));
}
print_r($array);
?>
The problem was that I want to have final data into the multidimensional array but I have only the title value but NOT the content.
Your loop is fine. To access the content get_the_content() you need to use setup_postdata. It sets up the global post data for template tags.
foreach ($posts as $post){
setup_postdata($post);
...
}
I'm trying to query wordpress post by using query_posts and trying to save them in an array so that I get retrieve the post from array. This is what I'm doing,
$posts= array();
$args = array('posts_per_page' =>3,'cat' => 3 );
$posts[] = query_posts( $args );
global $post;
if ( ! empty($posts) ) :
foreach ($posts as $post) {
setup_postdata($post);
echo get_the_title();
}
wp_reset_postdata();
endif;
wp_reset_query();
When I run this script it shows a post which is not in cat 3. but if I do print_r($post) it shows the correct three posts. Any idea of where I'm getting wrong?
No need to declare it as an array:
global $post;
$args = array('posts_per_page' => 3,'cat' => 3);
$query = query_posts($args);
foreach ($query as $post) {
setup_postdata($post);
the_title();
}
wp_reset_query();
This one should work also WP_Query or get_posts() is preferred method for secondary queries.
global $post;
$posts_args = array('cat' => 3, 'posts_per_page' => 3);
$posts_query = new WP_Query($posts_args);
$posts_arr = $posts_query->get_posts();
if ( ! empty($posts_arr) ) :
foreach ($posts_arr as $post) {
setup_postdata($post);
echo get_the_title();
}
wp_reset_postdata();
endif;
wp_reset_query();
Remember that query_posts modifies the main loop, so probably the post that is not from cat = 3 is from the main loop. Try to create a new query with get_posts.
$posts = get_posts('posts_per_page=3&cat=3');
global $post;
if (!empty($posts)):
foreach ($posts as $post):
setup_postdata($post);
echo get_the_title();
endforeach;
wp_reset_postdata();
endif;