WP Query foreach loop - repeats the same post - php

I have spent hours on this - hoping someone who knows a bit of PHP can solve it painlessly.
I have a Wordpress query loop which needs to be concatenated together. It kind of works, but I have requested 6 posts, and all 6 are the same!
Here's the code snippet which returns the duplicate posts:
////* New tab *//////
$args = array( 'numberposts' => 6, 'orderby' => 'post_date' );
$postslist = get_posts( $args );
$content .= '<div class="tab" id="new"><ul>';
foreach ($postslist as $post) : setup_postdata($post);
$content .= '<li><a href="' . get_permalink() . '"</a>' . get_the_title() . '</a></li>';
endforeach;
$content .= '</ul></div>';
return $content; // prints all the contents stringed together
This code produces this list:
Any help appreciated...at all! Thanks.

It looks like your code example is taken from inside a function.
a) Please try this:
// ... cut ...
global $post;
$args = array( 'posts_per_page' => 6, 'orderby' => 'post_date' );
$postslist = get_posts( $args );
$content .= '<div class="tab" id="new"><ul>';
foreach ( $postslist as $post ) : setup_postdata( $post );
$content .= sprintf( '<li>%s</li>',
get_permalink(),
get_the_title() );
endforeach;
$content .= '</ul></div>';
wp_reset_postdata();
return $content; // prints all the contents stringed together
where I added the global $post declaration so setup_postdata( $post ) can modify the global $post object.
b) Or try this:
// ... cut ...
$args = array( 'posts_per_page' => 6, 'orderby' => 'post_date' );
$postslist = get_posts( $args );
$content .= '<div class="tab" id="new"><ul>';
foreach ( $postslist as $post ) :
$content .= sprintf( '<li>%s</li>',
get_permalink( $post->ID ),
get_the_title( $post->ID ) );
endforeach;
$content .= '</ul></div>';
return $content; // prints all the contents stringed together
where I used the post id as an input argument for get_permalink() and get_the_title().
c) You can also use the raw post title: $post->post_title or if you want to take it through the the_title filter with:
echo apply_filters( 'the_title', $post->post_title );
So to wrap it up:
Notice that get_the_title() is based on get_post(), and if you don't use an input argument, then it will try to use the global $post object:
if ( empty( $post ) && isset( $GLOBALS['post'] ) )
$post = $GLOBALS['post'];
Therefore you always get the same global post object title (usually from the main query) if you don't modify the global object within the secondary loop.
Hope this helps.

Related

shortcode for related post in wp

I’m using bellow function for related post shortcode and I have a question about it. It’s supposed to display posts with related tag (I don't why it shows just random posts) but I want to use something like [rps tag=google] and the function just return a post has a tag as “google”, I mean nothing related to the current post tags. How can I do that?
This is the code:
add_shortcode('rps', 'fphp_get_related_posts');
function fphp_get_related_posts() {
$reset_post = $post;
global $post;
$post_tags = wp_get_post_tags($post->ID);
if ($post_tags) {
$post_tag_ids = array();
foreach($post_tags as $post_tag) $post_tag_ids[] = $post_tag->term_id;
$args=array(
'tag__in' => $post_tag_ids,
'post__not_in' => array($post->ID),
'posts_per_page' => 1,
'orderby' => 'rand',
);
$related_query = new wp_query( $args );
if (intval($related_query->post_count) === 0) return '';
$html = '<div class="rps"><ul><h3>Also read:</h3>';
$related_query->the_post();
$html .= '<li style="width:250px">';
$html .= '<div class="relatedthumb"><a rel="external" href="'. get_the_permalink(). '">';
$html .= get_the_title() . '</a>';
$html .= '</div></li>';
}
$post = $reset_post;
wp_reset_query();
$html .= '</ul></div>';
return $html;
}
If you want to show given tag post, then no need to use wp_get_post_tags(), because its return multi tags. try this code,
function fphp_get_related_posts( $atts ) {
$atts = shortcode_atts( [
'tag' => '',
], $atts );
$args = [ 'posts_per_page' => 1, 'tag' => $atts['tag'], 'orderby' => 'rand' ];
$query = new WP_Query( $args );
if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post();
ob_start(); ?>
<!-- your html here -->
<?php endwhile; endif; wp_reset_postdata();
return ob_get_clean();
}
add_shortcode( 'rps','fphp_get_related_posts' );

Display custom posts with shortcode

I've been searching this forum for help for 2 days now but I can't find a solution for what I'm trying to achieve.
I have a custom post type called "product" and inside each post in that post type there are two custom fields called produktnamn(a textfield with product name) and produktbild(a product image). that's it.
Now I need a shortcode to display a particular post in that post type by entering it's slug (which is the same as it's name).
like this:
[product name="myproduct"]
That will render the name and product image inside some HTML tags.
Please help!
My code so far:
//Product image
function cpt_content_func($atts){
extract( shortcode_atts(['name' => null], $atts ) );
$args = [
'name' => $slug,
'post_type' => 'product',
'numberposts' => 1
];
$posts = get_posts( $args );
$post = $post[0];
$title = $post->title;
$id = $post->ID;
get_post_meta('produktbild', $id);
$content = $post[0]->post_title;
return '<h3>'.$content.'</h3>';
}
add_shortcode('product','cpt_content_func');
Solved it. Here's the code!
function display_custom_post_type( $atts ){
// Handle the attributes
$atts = shortcode_atts(
array(
'cat' => ' '
),
$atts, 'products_by_cat' );
// Set default values for the post
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'post_status' => 'publish',
'category' => $atts['cat']
);
// Get posts
$posts_array = get_posts( $args );
// Check if posts exist
if( !empty($posts_array) ){
$string = '<div class="row">';
foreach( $posts_array as $post ){
$string .= '<div class="col-sm-3 text-center">';
$string .= '<div class="product-container">';
$string .= '<a href="' . get_field( "order_link", $post->ID ) . '">';
$string .= '<img class="product-img" src="' . get_field( "produktbild", $post->ID ) . '">';
$string .= '</a>';
$string .= '</div>';
$string .= '<p class="product-btn">' . get_field( "produktnamn", $post->ID ) . '</p>';
$string .= '</div>';
}
$string .= '</div>';
} else {
// Didn't find any posts.
}
// Return HTML
return $string;
I agree with James--I'd just use woocommerce.
But you first step has to be learning how to build a shortcode: http://code.tutsplus.com/tutorials/wordpress-shortcodes-the-right-way--wp-17165
Once you've attempted creating your own shortcodes, if things still aren't working, that's the time to ask for help.

How do I create a while loop within a PHP string?

I am creating a query using shortcodes ultimate lightbox. But the only way this will work within a regular php page, is to save the data as string. So what I need to do is to create my query but somehow get my results within a string.
Here is what works before I use any kind of php query:
<?php
$my_tabs = "<ul class='easybuttons'>
<li>[su_lightbox type='inline' src='#lightbox1']AT&T[/su_lightbox]</li>
<li>[su_lightbox type='inline' src='#lightbox2']Sprint[/su_lightbox]</li>
<li>[su_lightbox type='inline' src='#lightbox3']T-Mobile[/su_lightbox]</li>
</ul>";
echo do_shortcode( $my_tabs );
?>
but I need the ATT, Sprint, T-Mobile to be dynamic. Keep in mind the shortcode will only work if it within a string.
So how can I do a while loop within this string? I tried using an operator but did not work.
$args = array('post_type' => 'services', 'category_name' => $childid, 'order_by' => 'the_title', 'order' => 'ASC');
query_posts($args);
// The Query
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
$my_tabs .= '<ul class="easybuttons">';
while ( $the_query->have_posts() ) {
$the_query->the_post();
$my_tabs .= '<li>[su_lightbox type="inline" src="#lightbox1"]' . get_the_title() . '</li>';
}
$my_tabs .= '</ul>';
}
/* Restore original Post Data */
wp_reset_postdata();
echo do_shortcode( $my_tabs );
?>
UPDATE:
I tried using this code but it does work. Nothing comes through. I don't get any errors but no shortcode is displayed.
<?php
$args = array('post_type' => 'services', 'category_name' => $childid, 'order_by' => 'the_title', 'order' => 'ASC');
// The Query
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
$lid = 1;
$my_tabs .= '<ul class="easybuttons">';
while ( $the_query->have_posts() ) {
$the_query->the_post();
$my_tabs .= '<li>[su_lightbox type="inline" src="#lightbox' . $lid . '"]' . get_the_title() . '</li>';
$lid++;
}
$my_tabs .= '</ul>';
}
echo do_shortcode( $my_tabs );
wp_reset_postdata();
You need to initialise the variable $my_tabs somewhere, for instance outside the if block, and increment the lightbox id. You don't need to call query_posts(). order_by should be title, not the_title. Make sure $childid is definitely a string of the category slug, not the name, if in doubt, take out that parameter altogether to see if you get anything as I imagine this is most likely to be the main issue.
$args = array('post_type' => 'services', 'category_name' => $childid, 'order_by' => 'title', 'order' => 'ASC');
// The Query
$the_query = new WP_Query( $args );
$my_tabs = '';
// The Loop
if ( $the_query->have_posts() ) {
$lid = 1;
$my_tabs .= '<ul class="easybuttons">';
while ( $the_query->have_posts() ) {
$the_query->the_post();
$my_tabs .= '<li>[su_lightbox type="inline" src="#lightbox' . $lid . '"]' . get_the_title() . '</li>';
$lid++;
}
$my_tabs .= '</ul>';
}

Shortcode to list post titles from certain category

i found this great snippet of code on http://codex.wordpress.org/Template_Tags/get_posts and I edited it a little to suit me. It works.
<p>
<?php
$args = array( 'posts_per_page' => 0, 'offset'=> 0, 'category' => 1 );
$myposts = get_posts( $args );
foreach ( $myposts as $post ) : setup_postdata( $post ); ?>
<?php the_title(); ?>
</br>
<?php endforeach;
wp_reset_postdata();?>
</p>
I would like to transform it into a shortcode with one changeable variable - category id. But, well, since I don't know php, all I came up is:
function tytuly_postow($atts) {
extract(shortcode_atts(array(
'id' => 1,
), $atts));
$args = array( 'posts_per_page' => 0, 'offset'=> 0, 'category' => $id );
$q ="<p>
<?php
$myposts = get_posts( $args );
foreach ( $myposts as $post ) : setup_postdata( $post ); ?>
<?php the_title(); ?>
</br>
<?php endforeach;
wp_reset_postdata();?>
</p>";
}
add_shortcode('tytuly','lista_postow');
Of course, it doesn't work. I use Karma theme and added it in shortcodes.php file. Please, help :)
The code you have is certainly on the right track. Here's how I'd do it:
function tytuly_postow( $atts ) {
extract( shortcode_atts( array(
'id' => 1,
), $atts ) );
$posts = get_posts( array(
'posts_per_page' => -1,
'post_status' => 'publish',
'cat' => $id,
) );
$output = '';
if ( $posts ) {
$output .= '<p>';
foreach ( $posts as $post ) {
$output .= apply_filters( 'the_title', $post->post_title ) . '<br />';
}
$output .= '</p>';
}
return $output;
}
add_shortcode( 'tytuly', 'tytuly_postow' );
Offset by default is 0 so you don't need to add it as an argument. I've set posts_per_page to -1. This means get all.
Since you're just listing off titles it may make sense to order them by title. At the moment they'll be ordered by date descending.
I'm setting output to a blank string and returning output at the end. This means no matter what happens the shortcode will always return something, even if that something happens to be an empty string.
Then I'm checking if posts were found. If that's the case I'm adding a paragraph tag before and after the foreach. This was to match your original code.
Finally it loops through each post and uses the_title filter on the post titles then ends each title with a break tag.
By taking a look at the Shortcode API and add_shortcode Function Reference, you can check that the parameters of function add_shortcode are $tag and $func.
So, to start fixing your code, you need to fix it:
//[tutuly]
function tytuly_postow($atts) {
...
}
add_shortcode('tytuly', 'tytuly_postow');
By doing this, you will have a working structure for your shortcode. Now, your second mistake is that your function needs to return a value, thats what your shortcode will be transformed into. To do this, you need to use return.
Edit: Plus, your logic to retrive posts names was wrong, so I fixed it:
So, your fixed code will look like:
//[tutuly id="1"]
function tytuly_postow($atts) {
extract(shortcode_atts(array(
'id' => 1,
), $atts));
$args = array(
'posts_per_page' => -1,
'category' => $id,
'post_status' => 'publish'
);
$myposts = get_posts($args);
if ($myposts) {
$q = '<p>';
foreach ($myposts as $post) {
$q .= apply_filters('the_title', $post->post_title) . '<br />';
}
$q .= '</p>';
} else {
$q = '';
}
return $q;
}
add_shortcode('tytuly','tytuly_postow');
posts_per_page is now set to -1 to retrieve all posts,
post_status is used to retrieve only posts that are published.
If you want to retrieve links for your posts, instead of just the name, you can change this line:
$q .= apply_filters('the_title', $post->post_title) . '<br />';
to
$q .= '<a href=' . get_permalink($post->ID) . '>' . apply_filters('the_title', $post->post_title) . '</a><br />';
Notice that if you don't have enough programming skills, you can always use the awesome GenerateWP Shorcodes Generator.

WP -- Get posts by category?

I'm using this in my page template to get posts by their category:
<?php
if (is_page(19)){
?>
<ul>
<?php
global $post;
$args = array( 'category' => 'Testimonial' );
$myposts = get_posts( $args );
foreach( $myposts as $post ) : setup_postdata($post); ?>
<li class="testimonial"><?php the_content(); ?></li><br/>
<?php endforeach; ?>
</ul>
<?php } ?>
but it's retrieving all posts instead. Not just the ones labeled Testimonial. Any idea what I'm doing wrong?
'category_name'=>'this cat' also works but isn't printed in the WP docs
Check here : https://developer.wordpress.org/reference/functions/get_posts/
Note: The category parameter needs to be the ID of the category, and
not the category name.
You can use 'category_name' in parameters.
http://codex.wordpress.org/Template_Tags/get_posts
Note: The category_name parameter needs to be a string, in this case, the category name.
add_shortcode( 'seriesposts', 'series_posts' );
function series_posts( $atts )
{ ob_start();
$myseriesoption = get_option( '_myseries', null );
$type = $myseriesoption;
$args=array( 'post_type' => $type, 'post_status' => 'publish', 'posts_per_page' => 5, 'caller_get_posts'=> 1);
$my_query = null;
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) {
echo '<ul>';
while ($my_query->have_posts()) : $my_query->the_post();
echo '<li><a href="';
echo the_permalink();
echo '">';
echo the_title();
echo '</a></li>';
endwhile;
echo '</ul>';
}
wp_reset_query();
return ob_get_clean(); }
//this will generate a shortcode function to be used on your site [seriesposts]
Create a taxonomy field category (field name = post_category) and import it in your template as shown below:
<?php
$categ = get_field('post_category');
$args = array( 'posts_per_page' => 6,
'category_name' => $categ->slug );
$myposts = get_posts( $args );
foreach ( $myposts as $post ) : setup_postdata( $post ); ?>
//your code here
<?php endforeach;
wp_reset_postdata();?>

Categories