I need to create a recent posts section outside a WordPress website, but the result is incorrect (see image). I used this PHP code:
// elsewhere in code...
require "wp-load.php";
// the code that is generating the recent posts section
$posts = get_posts( array( 'posts_per_page' => 1 ) );
$recent_posts = wp_get_recent_posts(array('numberposts' => 7 ) );
foreach ($posts as $_post) {
foreach($recent_posts as $post) {
if ( has_post_thumbnail( $_post->ID ) ) {
echo '<div class="owl-item">';
echo '<figure class="blog-item-container">';
echo '<span class="blog-item-img">';
echo get_the_post_thumbnail( $_post->ID, array(480, 305) );
echo '</span>';
echo '<figcaption>';
echo '<h3>', $post['post_title'], '</h3>';
echo '</figcaption>';
echo '</figure>';
echo '</div>';
}
}
}
I was expecting to get the image for each specific recent post. This result gives to me the correct recent post, but the image is the same for all the posts. Why is the image the same?
Here's some comments on your code, which will hopefully explain what's going wrong, or help you get to the bottom of it:
// Here you are getting ONE post for some reason, and putting it in the $posts variable
$posts = get_posts( array( 'posts_per_page' => 1 ) );
// Here you are getting 7 posts, and putting in the $recent_posts variable
$recent_posts = wp_get_recent_posts(array('numberposts' => 7 ) );
// Here you are "looping" over the ONE post and putting into $_post variable.
// So here, $_post is made to reference the single most recent post
foreach ($posts as $_post) {
// Here, you are "looping" over the 7 recent posts, putting into $post variable
foreach($recent_posts as $post) {
// Here you ask if the ONE most recent post ($_post) has a featured image.
// I doubt this is what you actually want, as this will
// be run for all 7 recent posts, but is only referencing
// the single ONE post
if ( has_post_thumbnail( $_post->ID ) ) {
echo '<div class="owl-item">';
echo '<figure class="blog-item-container">';
echo '<span class="blog-item-img">';
// here you are displaying the image for the ONE post, not the 7 most recent posts
echo get_the_post_thumbnail( $_post->ID, array(480, 305) );
echo '</span>';
echo '<figcaption>';
// Here you are referencing the title, link, etc.
// for the 7 most recent posts
echo '<h3>', $post['post_title'], '</h3>';
echo '</figcaption>';
echo '</figure>';
echo '</div>';
}
}
}
So, given your question of "recent posts", and your comment that it is incorrect to show the same featured image for all of them, I suspect the code should look like this (NOTE: you can remove all of the commented code, I left it here to explain what the changes are):
// remove this - no need for the single most recent post
// $posts = get_posts( array( 'posts_per_page' => 1 ) );
$recent_posts = wp_get_recent_posts(array('numberposts' => 7 ) );
// remove this - don't loop over the single most recent post
// foreach ($posts as $_post) {
foreach($recent_posts as $post) {
// change this to $post['ID'] (from $_post->ID)
if ( has_post_thumbnail( $post['ID'] ) ) {
echo '<div class="owl-item">';
echo '<figure class="blog-item-container">';
echo '<span class="blog-item-img">';
// change this to $post['ID'] (from $_post->ID)
echo get_the_post_thumbnail( $post['ID'], array(480, 305) );
echo '</span>';
echo '<figcaption>';
echo '<h3>', $post['post_title'], '</h3>';
echo '</figcaption>';
echo '</figure>';
echo '</div>';
}
}
// remove this, since we are removing the loop
// }
Related
I have tried to find a solution to something I need on the website (example here: https://www.baiweb.nl/). I have been looking for a way to show a custom number of posts per category AND sort them by date. I have managed to get a single post per category, but I can't seem to fix the rest. It sorts the posts itself by date now, but not all of them.
So, my questions are:
Is it possible to sort this loop, with all different categories, by date?
Is it possible to control the number of posts shown per category? This one is extra for me, not essential, but it would be nice.
Hope someone can help! Thanks a lot in advance for your time!
Here is my code used in the loop now:
<?php
$categories = get_categories();
$cats = array();
foreach($categories as $category) {
$cats[] = $category->name . ", ";
}
$exclude_posts = array();
foreach( $cats as $cat ) {
// build query argument
$query_args = array(
'category_name' => $cat,
'showposts' => 1,
'post_type' => 'post',
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC'
);
// exclude post that already have been fetched
// this would be useful if multiple category is assigned for same post
if( !empty($exclude_posts) )
$query_args['post__not_in'] = $exclude_posts;
// do query
$query = new WP_Query( $query_args );
// check if query have any post
if ( $query->have_posts() ) {
// start loop
while ( $query->have_posts() ) {
// set post global
$query->the_post();
// add current post id to exclusion array
$exclude_posts[] = get_the_ID();
?>
<article id="post-<?php the_ID(); ?>" <?php post_class('loop');?>>
<div class="corner"><span><?php foreach((get_the_category()) as $category){ echo $category->name.'<br> '; } ?></span></div>
<!-- thumbnail -->
<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>" class="image">
<?php
$thumb_id = get_post_thumbnail_id();
$thumb_url = wp_get_attachment_image_src($thumb_id,'medium', true);
if ( in_category('2') || in_category('32') ) {
echo '<div class="newstitle">' . the_title() . '</div>';
}
else {
if ( has_post_thumbnail()) {
echo "<div class='ctr-image test2' style='background-image: url(" . $thumb_url[0] . ")'></div>";
}
else {
echo '<div class="newstitle">' . the_title() . '</div>';
}
}
?>
</a>
<div class="content">
<span class="date"><?php the_time('j/m/Y'); ?></span>
<h3>
<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
<?php if ( in_category('2') || in_category('32') ) {}
else { echo the_title();} ?>
</a>
</h3>
<div class="text">
<?php html5wp_excerpt('html5wp_index'); // Build your custom callback length in functions.php ?>
</div>
</div>
</article>
<?php
// do something
}
} else {
// no posts found
}
// Restore original Post Data
wp_reset_postdata();
} ?>
You were close. Your categories foreach loop has to englobe everything. Then we do a simple loop but we specify what arguments to use depending on each categories.
Here is our final result.
<?php
$categories = get_categories(); // ... get all our categories
foreach( $categories as $category ) { // ... start foreach categories
if ( $category->name == 'Mercury' ) { // ... if our category name is 'Mercury'
$posts_per_page = 1; // ... 1 post per page if our category is named 'Mercury'
} else { // ... else, for all other categories
$posts_per_page = 3; // ... 3 posts per page
};
$args = array( // ... all our arguments
'posts_per_page' => $posts_per_page, // ... 1 or 3 posts per page depending on our categories
'post_type' => 'post',
'category_name' => $category->name,
'post_status' => 'publish',
'orderby' => 'date', // ... order by date
'order' => 'ASC', // ... most recent first
);
$query = new WP_Query( $args ); // .. start a new loop
if( $query->have_posts() ):
echo '<section>';
echo '<h1>' . $category->name . '</h1>'; // ... only display our section IF a post exist in the category
while( $query->have_posts() ): $query->the_post();
echo '<article>'; // ... our post template
the_title( '<h4>', '</h4>' );
echo '</article>';
endwhile;
echo '</section>';
endif;
wp_reset_postdata(); // ... After looping through a separate query, this function restores the $post global to the current post in the main query.
}; // ... end foreach categories
?>
Thank you so much for your quick and comprehensive answer! The part of the number of categories is working very well, however, the outcome is slightly different than I want. It may be that my question was not clear, apologies for that.
What you have already made beautiful is all the categories with posts that belong to it. What I want to achieve is that all messages are mixed up, sorted by date and, what was already done here, I can indicate how many posts are in per category. Is that even possible?
Some screenshotsof the outcome of your code:
This is what I am trying, except now I need to sort this by date:
This is the code slightly adjusted:
<?php
$categories = get_categories(); // ... get all our categories
foreach( $categories as $category ) { // ... start foreach categories
if ( $category->name == 'Mercury' ) { // ... if our category name is 'Mercury'
$posts_per_page = 1; // ... 1 post per page if our category is named 'Mercury'
} else { // ... else, for all other categories
$posts_per_page = 2; // ... 3 posts per page
};
$args = array( // ... all our arguments
'posts_per_page' => $posts_per_page, // ... 1 or 3 posts per page depending on our categories
'post_type' => 'post',
'category_name' => $category->name,
'post_status' => 'publish',
'orderby' => 'date', // ... order by date
'order' => 'ASC', // ... most recent first
);
$query = new WP_Query( $args ); // .. start a new loop
if( $query->have_posts() ):
// echo '<section>';
// echo '<h1>' . $category->name . '</h1>'; // ... only display our section IF a post exist in the category
while( $query->have_posts() ): $query->the_post();
echo '<article>'; // ... our post template
echo '<h1>' . $category->name . '</h1>';
the_time('j/m/Y');
the_title( '<h4>', '</h4>' );
echo '</article>';
endwhile;
// echo '</section>';
endif;
wp_reset_postdata(); // ... After looping through a separate query, this function restores the $post global to the current post in the main query.
}; // ... end foreach categories ?>
Hope this is clear, thanks again!
I know this question has been asked before. I checked through multiple answers on this site,
for example:
Wordpress loop with different bootstrap columns
https://wordpress.stackexchange.com/questions/222278/how-to-separate-posts-loop-in-to-two-columns/222281
... but I cannot work out how to integrate answers with my code (assuming that is possible).
I want to display a list of Categories and their related posts on a page.
The code I'm using works fine BUT displays the results in a single column down the page:
I want to split the display into 2 columns, like in the image below, if possible:
The code I'm using (currently placed in a new page template) is as follows:
<?php
/*
* Template Name: Alphabetical List
*/
get_header();
// Grab all the categories from the database that have posts.
$categories = get_terms( 'category', 'orderby=name&order=ASC');
// Loop through categories
foreach ( $categories as $category ) {
// Display category name
echo '<h2 class="post-title">' . $category->name . '</h2>';
echo '<div class="post-list">';
// WP_Query arguments
$args = array(
'cat' => $category->term_id,
'order' => 'ASC',
'orderby' => 'title',
);
// The Query
$query = new WP_Query( $args );
// The Loop
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
?>
<p><?php the_title(); ?></p>
<?php
} // End while
} // End if
echo '</div>';
// Restore original Post Data
wp_reset_postdata();
} // End foreach
get_footer();
?>
Wondering if anyone can help me to get this code to display loop results in 2 columns.
Many thanks.
UPDATE TO QUESTION
Karl, thanks for your answer. Your script works, but with a small problem:
The Categories/Related Posts display in 2 columns but a 'gap/space' appears in the middle of the display of data (see image below):
I added to your code slightly so I could display a custom field I inserted into each post. I'm not sure if this has caused the problem.
Altered code (changes are immediately after $query->the_post();):
<?php
/*
* Template Name: Alphabetical List
*/
get_header();
?>
<div style="height:100px"></div>
<?php
// Grab all the categories from the database that have posts.
$categories = get_terms( 'category', 'orderby=name&order=ASC');
// Loop through categories
echo "<div class='new-column'>";
$counter = 0;
foreach ( $categories as $category ) {
if($counter % 4 == 0 && $counter !=0){
echo "<div class='new-column'>";
}
// Display category name
echo '<h2 class="post-title">' . $category->name . '</h2>';
echo '<div class="post-list">';
// WP_Query arguments
$args = array(
'cat' => $category->term_id,
'order' => 'ASC',
'orderby' => 'title',
);
// The Query
$query = new WP_Query( $args );
// The Loop
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
$customfieldvalue = get_post_meta($post->ID, "PDF", true);
?>
<p><a href="<?php echo $customfieldvalue; ?>" target="_blank"><?php
the_title(); ?></a></p>
<?php
} // End while
} // End if
echo '</div>';
// Restore original Post Data
wp_reset_postdata();
$counter++;
if($counter % 4 == 0){
echo "</div>";
}
} // End foreach
if($counter % 4 != 0){
echo "</div>";
}
get_footer();
?>
I've used bootstrap classes (row, col-6). Checked the size of categories array and used 2 variables - one as a counter and the other one to check if the column is first or second.
<?php
/*
* Template Name: Alphabetical List
*/
get_header();
// Grab all the categories from the database that have posts.
$categories = get_terms( 'category', 'orderby=name&order=ASC');
//get size of category
$catSize = sizeof($categories);
$j = 1;
$n = 1;
// Loop through categories
foreach ( $categories as $category ) {
if($n == 1){
echo '<div class="row">';
}
echo'<div class="col-6">';
// Display category name
echo '<h2 class="post-title">' . $category->name . '</h2>';
echo '<div class="post-list">';
// WP_Query arguments
$args = array(
'cat' => $category->term_id,
'order' => 'ASC',
'orderby' => 'title',
);
// The Query
$query = new WP_Query( $args );
// The Loop
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
?>
<p><?php the_title(); ?></p>
<?php
} // End while
} // End if
echo '</div></div>';
if($n == 1){
if($j == $catSize){
echo '<div class="col-6"></div>
</div>';
}
else{
$n = 2;
}
}
else{
echo '</div>';
$n =1;
}
$j++;
}
// Restore original Post Data
wp_reset_postdata();
} // End foreach
get_footer();
?>
Try this, I used a modulos operator "%" to group loops into 4, it will create new column every 4 loops. MAKE SURE YOU ADD CSS TO class new-column to arrange it like columns.
<?php
/*
* Template Name: Alphabetical List
*/
get_header();
// Grab all the categories from the database that have posts.
$categories = get_terms( 'category', 'orderby=name&order=ASC');
// Loop through categories
echo "<div class='new-column'">;
$counter = 0;
foreach ( $categories as $category ) {
if($counter % 4 == 0 && $counter !=0){
echo "<div class='new-column'">;
}
// Display category name
echo '<h2 class="post-title">' . $category->name . '</h2>';
echo '<div class="post-list">';
// WP_Query arguments
$args = array(
'cat' => $category->term_id,
'order' => 'ASC',
'orderby' => 'title',
);
// The Query
$query = new WP_Query( $args );
// The Loop
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
?>
<p><?php the_title(); ?></p>
<?php
} // End while
} // End if
echo '</div>';
// Restore original Post Data
wp_reset_postdata();
$counter++;
if($counter % 4 == 0){
echo "</div>";
}
} // End foreach
if($counter % 4 != 0){
echo "</div>";`enter code here`
}
get_footer();
?>
I am trying to create a a page in wordpress where I show 5 recent posts.
I was able to successfully do that.
However, I am not able to retrieve images that are present inside that post.
I am using this code to retrieve post url and post image. (Post URL works fine!)
$args = array('numberposts'=>'5');
$recentposts = wp_get_recent_posts($args);
foreach($recentposts as $post){
$v = $post['ID'];
$postlink = get_permalink($v);
$postimg = get_the_post_thumbnail($v);
}
try below code
$posts = get_posts( array( 'posts_per_page' => 5 ) );
foreach ( $posts as $_post ) {
if ( has_post_thumbnail( $_post->ID ) ) {
echo '<a href="' . get_permalink( $_post->ID ) . '" title="' . esc_attr( $_post->post_title ) . '">';
echo get_the_post_thumbnail( $_post->ID, 'thumbnail' );
echo '</a>';
}
}
I'm trying to get a category and loop through its sub categories getting one post from each of those sub-categories. Below is my code:
<?
$homepage_cat = get_category_by_slug( 'home-page-slider' );
$id = $homepage_cat->cat_ID;
print($id);
$sub_cat = get_categories('hide_empty=0&child_of=' . $id);
print_r($sub_cat);
foreach ($sub_cat as $key => $cat)
{
echo $cat->term_id;
query_posts('cat=' . $cat->term_id);
if ( have_posts() )
{ echo '<h1> HELL YEAH </h1>';
while ( have_posts() )
{
echo '<h1>' get_the_title(); '</h1>';
} // end while
} // end if
} //end foreach
?>
The code is not returing any posts as HELL YEAH is not being echoed. Can anyone suggest a solution?
Use get_posts() not query_posts, it is better for these kinds of situations.
$args = array('posts_per_page' => 1, 'category' => $cat->term_id);
$posts = get_posts($args);
foreach($posts as $post) : setup_postdata( $post ) ?>
<h1><?php get_the_title(); ?></h1>
<?php endforeach; ?>
There are quite a few problems here
First of all, never use query_posts to construct custom queries. It breaks the main query, is unreliable and outright fails in most cases in pagination
Secondly, you have to reset your postdata after every custom query
Thirdly, never use short tags. Always use full tag ie <?php and not just <?
Lastly, you are missing the_post() which should return post objects
Your query should look something like this
<?php
$homepage_cat = get_category_by_slug( 'home-page-slider' );
$id = $homepage_cat->cat_ID;
print($id);
$sub_cat = get_categories('posts_per_page=1&hide_empty=0&child_of=' . $id);
print_r($sub_cat);
foreach ($sub_cat as $key => $cat)
{
echo $cat->cat_ID;
$q = new WP_Query('cat=' . $cat->cat_ID);
if ( $q->have_posts() )
{ echo '<h1> HELL YEAH </h1>';
while ( $q->have_posts() )
{
$q->the_post();
echo '<h1>' get_the_title(); '</h1>';
} // end while
} // end if
wp_reset_postdata();
} //end foreach
?>
Replace this
$post_args = array(
'showposts' => 1,
'cat' => $cat->term_id
);
with this.
$post_args = array(
'posts_per_page' => 1,
'category' => $cat->term_id
);
I hope it'll work.
So I'm trying to write a new plugin since I haven't been able to find one that does exactly what I want with the extensibility that I desire. The goal of the plugin is to be able to use a simple shortcode to display an image slider that automatically populates with your blog's latest posts.
I've got the basic plugin files ready and the shortcode implemented and tested. I had a snafu solved yesterday on SO but the solution highlighted a new problem. Here's the code:
function slyd( $category, $slydcount ) {
global $post;
$tmp_post = $post; // Create $tmp_post to empty $post once Slyd is done with it
$args = array(
'category' => $category,
'numberposts' => $slydcount
);
$slydposts = get_posts( $args );
foreach( $slydposts as $post ) : setup_postdata($post);
$post_title = get_the_title(); // Get the post's title
$post_content = get_the_content(); // Get the post's content - will write code to get excerpt later
$post_thumb = wp_get_attachment_image_src( get_post_thumbnail_id(), 'full' ); // Get the post's featured image's src
$post_permalink = get_permalink(); // Get the post's permalink
echo '<h2>' . $post_title . '</h2>'
. '<p>' . $post_content . '</p>'
. '<p>' . $post_thumb . '</p>';
endforeach;
$post = $tmp_post; // Empty $post once Slyd is done with it
}
// Create the shortcode
function slyd_shortcode( $atts ) {
// $atts ::= array of attributes
// examples: [slyd]
// [slyd category='slide']
// [slyd slydcount='5']
// [slyd theme='default']
/* Retrieve attributes set by the shortcode and set defaults for
unregistered attributes. */
extract( shortcode_atts( array(
'category' => 'slyd', // Which category(s) to display posts from
'slydcount' => '5', // How many Slyds to display
'theme' => 'default' // Which Slyd theme to use
), $atts ) );
return "<p>category = {$category}, count = {$slydcount}</p>"
. slyd( $category, $slydcount );
}
add_shortcode( 'slyd', 'slyd_shortcode' );
The issue is in the foreach loop in function slyd();. I was originally using a return where the echo is now to put the result on the screen. That worked to display the first post but it would, of course, escape the function. I need it to cycle through and display all of the posts.
From researching the PHP documentation I found that I could use print in place of echo or return but it's giving me the same result as echo. What's happening is the code seems to be executing twice. It places itself where it needs to be the first time, then it also echoes to the browser and places it just below the head of the page.
I suppose my question is whether there's an alternative to return, echo, or print that would solve my problem?
Thanks in advance.
Now I'm trying to get the plugin to pull in the blog's latest posts but I'm running into a bit of a snafu. When I use the_title() and the_permalink() they display outside of the code I'm trying to contain them in. Further, the_content() is displaying once with the_permalink() and the_title() and then a second time where it's supposed to.
You can see the behavior here.
return is what you want in this case. You want to return a value (i.e. html code) from the slyd function so you can use it (in this case append it) in the slyd_shortcode function. However, you need to first collect all output into an additional variable ($ret below), and then return that value:
function slyd( $category, $slydcount ) {
global $post;
$tmp_post = $post;
$args = array(
'category' => $category,
'numberposts' => $slydcount
);
$slydposts = get_posts( $args );
$ret = '';
foreach( $slydposts as $post ) {
setup_postdata($post);
$post_title = get_the_title();
$post_content = get_the_content();
$post_thumb = wp_get_attachment_image_src( get_post_thumbnail_id(), 'full' );
$post_permalink = get_permalink();
$ret .= '<h2>' . $post_title . '</h2>'
. '<p>' . $post_content . '</p>'
. '<p>' . $post_thumb . '</p>';
}
$post = $tmp_post;
return $ret;
}
As you see you should first initialize the $ret variable with an empty string, then append to it on each iteration of the foreach loop. return is used to return the whole string after the loop.