I am in search of the best way to display pages active posts categories and expired after a certain period. I want to display active posts or have no expiration date in the main loop and those that expire in a loop below.
For this I used the plugin advanced custom field ( expiration ) which define the expiration date. With loops below, I get the result I want, however, would help to improve. For example, in the loop of expired posts, the H2 tag appears on the page even if there are no expired posts, and if I move it under the condition "if ( $ exhale < $ blogtime )", it appears in all expired posts, what do not want, I want to appear only once above all expired posts.
Another question I have is whether these loops will somehow require more work from the server, since it will have to make new appointments.
<?php if ( have_posts() ) : ?>
<?php if ( is_home() && ! is_front_page() ) : ?>
<header>
<h1 class="page-title screen-reader-text"><?php single_post_title(); ?></h1>
</header>
<?php endif; ?>
<?php
// Start the loop.
while ( have_posts() ) : the_post();
$blogtime = date( 'm/d/Y H:i:s', current_time( 'timestamp', 0 ) );
$blogt = date( '0' );
$expire = get_field('expiration');
if( $expire > $blogtime ) {
get_template_part( 'template-parts/content', get_post_format() ); }
elseif( $expire < $blogt ) {
get_template_part( 'template-parts/content', get_post_format() ); }
// End the loop.
endwhile;
endif;
?>
<?php
$args = array(
'post_type' => array('post','news'),
'posts_per_page' => 15,
'cat' => $cat,
'meta_key' => 'expiration',
'orderby' => 'meta_value_num',
'order' => 'DESC',
);
$eventloop = new WP_Query($args);
if ( $eventloop->have_posts() ) :
echo '<h2>Expired</h2>';
while ( $eventloop->have_posts() ) : $eventloop->the_post();
$blogtime = date( 'm/d/Y H:i:s', current_time( 'timestamp', 0 ) );
$blogt = date( '0' );
$expire = get_field('expiration');
if( $expire < $blogtime ) {
if ( $expire > $blogt ) {
get_template_part( 'template-parts/content', get_post_format() );
} }
endwhile;
endif;
?>
Related
I am having issues with the functionality of my code. The custom post should expire after a certain number of days. At the moment it’s set to 3 days just so I can test it.
But the posts are expiring even though the expiry date is before today's date, and I can’t figure out why?!
// Setup Cron Job Function to expire posts and send out emails.
function listing_expiry_date() {
// Get the current date
date_default_timezone_set('Europe/London');
$today = date('m/d/Y');
// Custom Post Type for listings, grab published posts
$args = array(
'post_type' => array( 'post_type_listings' ),
'post_status' => array( 'Publish' ),
'posts_per_page' => -1,
);
// The Query
$query = new WP_Query( $args );
// The Loop
if ( $query->have_posts() ) :
while ( $query->have_posts() ) :
$query->the_post();
// Get the listing ID
$post_id = get_the_ID();
// Get listing post published date (not pending date)
$published_date = get_the_date( 'm/d/Y', get_the_ID() );
$expiry_date = date( 'm/d/Y', strtotime( '+3 days', strtotime($published_date) ) );
// If todays date is equal to or greater than the expiry date...
if ( ($today == $expiry_date) || ($today > $expiry_date) ) :
// change post status to 'expired'
$postdata = array(
'ID' => $post_id,
'post_status' => 'expired',
);
// Update post data
wp_update_post($postdata);
endif;
endwhile; //endwhile The Loop
endif; //endif The Loop
}
IT seems your issue would be how you're evaluating the dates. In this case, it would be best to use a Unix timestamp to evaluate which is greater.
function listing_expiry_date() {
// Get the current date.
date_default_timezone_set( 'Europe/London' );
$today = date( 'U' );
// Custom Post Type for listings, grab published posts.
$args = array(
'post_type' => array( 'post_type_listings' ),
'post_status' => array( 'publish' ),
'posts_per_page' => -1,
);
// The Query.
$query = new WP_Query( $args );
// The Loop.
if ( $query->have_posts() ) :
while ( $query->have_posts() ) :
$query->the_post();
// Get the listing ID.
$post_id = get_the_ID();
$expiry_date = date( 'U', strtotime( '+3 days', get_the_date( 'U', $post_id ) ) );
// If Expiration date is < or = today.
if ( $expiry_date <= $today ) :
// change post status to 'expired'
$postdata = array(
'ID' => $post_id,
'post_status' => 'expired',
);
// Update post data.
wp_update_post($postdata);
endif;
endwhile; // endwhile The Loop.
endif; // endif The Loop.
}
My archive page with added numeric pagination won't sort out the right category and instead shows posts from all the categories. Let's say the category is bananas (http://localhost/tkeblog/category/bananas/) and I get post from categories bananas, oranges and apples. Also the pagination system doesn't show posts with thumbail yet it works on my index.php page. What am I doing incorrectly to filter the posts by category?
<?php
if ( get_query_var('paged') ) { $paged = get_query_var('paged'); }
elseif ( get_query_var('page') ) { $paged = get_query_var('page'); }
else { $paged = 1; }
query_posts(array(
'post_type' => 'post', // You can add a custom post type if you like
'paged' => $paged,
'posts_per_page' => 5
));
if ( have_posts() ) : the_post(); ?>
<div class="blogitem a">
<?php while ( have_posts() ) : the_post(); ?>
<?php get_template_part('catalog',get_post_format()); ?>
<?php endwhile; ?>
<div class="pagination">
<?php my_pagination(); ?>
</div>
</div>
<?php else: ?>
<p>Sorry, no posts matched your criteria.</p>
<?php wp_reset_query(); ?>
<?php endif; ?>
If we take a look at the default TwentyTwentyOne Wordpress theme archive.php we can see that the archive template is just using a default loop to display all posts from all categories, not a custom query.
I believe this answers your question.
<?php
if( have_posts() ):
while( have_posts() ): the_post();
// ... template
endwhile;
else:
// ... fallback
endif; ?>
If you want to customize the default query output from the archive.php page, the best practice is to do it from your function.php page. You can use the the action hook filter pre_get_posts.
Source # https://developer.wordpress.org/reference/hooks/pre_get_posts/
Fires after the query variable object is created, but before the actual query is run. Be aware of the queries you are changing when using the pre_get_posts action. Make use of conditional tags to target the right query.
<?php
add_action( 'pre_get_posts', function ( $query ) {
if ( ! is_admin() && $query->is_archive() && $query->is_main_query() ) {
if ( get_query_var( 'post_type' ) == 'post' ) {
$query->set( 'post_type', array( 'post' ) );
$query->set( 'posts_per_page', 12 );
$query->set( 'orderby', array( 'date' ) );
$query->set( 'order', array( 'ASC' ) );
} else {
$query->set( 'posts_per_page', 6 );
$query->set( 'orderby', array( 'date' ) );
$query->set( 'order', array( 'ASC' ) );
};
};
}; ?>
So I am using WordPress with an underscores theme. I used code from twenty fourteen's theme with pagination.
if ( ! function_exists( 'public_notices_paging_nav' ) ) :
function public_notices_paging_nav() {
global $wp_query, $wp_rewrite;
// Don't print empty markup if there's only one page.
if ( $wp_query->max_num_pages < 2 ) {
echo ("<h4 class='one-page-results'>End of Results</h4>");
return;
}
$paged = get_query_var( 'paged' ) ? intval( get_query_var( 'paged' ) ) : 1;
$pagenum_link = html_entity_decode( get_pagenum_link() );
$query_args = array();
$url_parts = explode( '?', $pagenum_link );
if ( isset( $url_parts[1] ) ) {
wp_parse_str( $url_parts[1], $query_args );
}
$pagenum_link = remove_query_arg( array_keys( $query_args ), $pagenum_link );
$pagenum_link = trailingslashit( $pagenum_link ) . '%_%';
$format = $wp_rewrite->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
$format .= $wp_rewrite->using_permalinks() ? user_trailingslashit( $wp_rewrite->pagination_base . '/%#%', 'paged' ) : '?paged=%#%';
// Set up paginated links.
$links = paginate_links( array(
'base' => $pagenum_link,
'format' => $format,
'total' => $wp_query->max_num_pages,
'current' => $paged,
'mid_size' => 1,
'add_args' => array_map( 'urlencode', $query_args ),
'prev_text' => __( '← Previous', 'public_notices' ),
'next_text' => __( 'Next →', 'public_notices' ),
'type' => 'list',
) );
if ( $links ) :
?>
<nav class="navigation paging-navigation" role="navigation">
<h1 class="screen-reader-text"><?php _e( 'Posts navigation', 'public_notices' ); ?></h1>
<?php echo $links; ?>
</nav><!-- .navigation -->
<?php
endif;
}endif;
This worked great when I only had one post type, but now I've made a loop that displays two post types and it works. But on every page its the same group of posts.
<?php
$postLoop = array(
'post_type' => array('public_notice_post', 'post'),
'orderby' => 'date',
'order' => 'DESC'
);
$query = new WP_Query( $postLoop );
if ($query->have_posts()) :
while ($query->have_posts()) : $query->the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
public_notices_paging_nav();
endif;
wp_reset_query(); ?>
Anything will help. I've tried a lot.
Maybe you got a loop with no "wp_reset_query()" and this may caused some bugs on other loop.. just look all your loop to be sure there noone without reset query.
On which kind of page you coded this loop ? This is a custom template or other ?
Sorry for my english, im french.
To fix the original problem of duplicated posts on every page all I had to do was write my code like this. HOWEVER I am still having an issue of page count, but that will addressed elsewhere.
<?php
$page = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
$ppp = get_option( 'posts_per_page' );
if ( $page == 1 )
$offset = 6;
else
$offset = 6 + ( $page - 1 ) * $ppp;
?>
<?php
$postLoop = array(
'post_type' => array('public_notice_post', 'post'),
'orderby' => 'date',
'order' => 'DESC',
'paged' => $paged,
'posts_per_page'=> $ppp,
'offset' => $offset
);
$wp_query = new WP_Query( $postLoop );
if ($wp_query->have_posts()) :
while ($wp_query->have_posts()) : the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
public_notices_paging_nav();
endif;
wp_reset_query(); ?>
I am using 2 custom queries to load posts on a custom Wordpress template homepage.
the first query loads 4 'sticky' posts, and the next query loads several more recent posts.
This works great and does what I need it to do, but the pagination links when clicked show the same content on every page.
For example I have 10 posts on the homepage, and when i click to page 2 - the exact same 10 posts appear again. If I click pagination to visit page 3, the same 10 posts again etc.
No matter what page I am on, the same 10 posts are listed.
I have read something about paged being required but several failed attempts to include that in my below code have broguht me here.
Any ideas appreciated!
My code...
<?php $sticky = get_option( 'sticky_posts' );
$args = array(
'posts_per_page' => 4,
'post__in' => $sticky,
'ignore_sticky_posts' => 1,
); ?>
<?php $the_query = new WP_Query( $args ); ?>
<?php if ( $the_query->have_posts() ) : ?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
<?php endif; ?>
<main id="main" class="site-main" role="main">
<?php $the_query = new WP_Query( array( 'post__not_in' => get_option( 'sticky_posts' ) ) );
if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<?php get_template_part( 'content', get_post_format() ); ?>
<?php endwhile; ?>
<?php else : ?>
<?php get_template_part( 'content', 'none' ); ?>
<?php endif; ?>
You sure need the $paged parameter (docs). Untested but give it a go:
<?php
// $paged holds the current page offset
$paged = ( get_query_var('paged') ) ? get_query_var( 'paged' ) : 1;
/**
* - Checks if the current page is 'paged' (false on first page)
* - Remove the check if you need those sticky posts on all pages
* - I added the $paged parameter so those sticky posts will paginate
* if you decide to show them on all pages
*
*/
if( ! is_paged() ) { // Sticky posts only on first page
$sticky = get_option( 'sticky_posts' );
$args = array(
'posts_per_page' => 4,
'post__in' => $sticky,
'ignore_sticky_posts' => 1,
'paged' => $paged // ah, the page offset
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
?>
<?php the_title(); ?>">
<?php
}
} else {
?>
<p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
<?php
}
wp_reset_postdata();
}
?>
<main id="main" class="site-main" role="main">
<?php
$args = array(
'post__not_in' => get_option( 'sticky_posts' ),
'paged' => $paged // ah, the page offset
);
// can be done via new WP_Query but today I am lazy
// also see http://codex.wordpress.org/Function_Reference/query_posts
query_posts($args);
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
get_template_part( 'content', get_post_format() );
}
} else {
get_template_part( 'content', 'none' );
}
wp_reset_query();
?>
I am using the below query to show 4 most recent sticky posts in Wordpress.
<?php
$sticky = get_option( 'sticky_posts' ); // Get all sticky posts
rsort( $sticky ); // Sort the stickies, latest first
$sticky = array_slice( $sticky, 0, 4 ); // Number of stickies to show
query_posts( array( 'post__in' => $sticky, 'caller_get_posts' => 1 ) ); // The query
if (have_posts() ) { while ( have_posts() ) : the_post(); ?>
ALL OF MY OUTPUTTED CODE GOES HERE - EDITED OUT TO SAVE SPACE
<?php endwhile;?>
<?php } else { echo ""; }?>
<?php wp_reset_query(); ?>
This works great but if I have a scheduled sticky post (to appear at a future date), the query ignores it as one of the sticky posts and only shows 3 - not the 4 it should?
How can I modify below code to make sure no scheduled sticky posts show AND I still retain 4 slots for sticky posts?
UPDATED CODE BELOW SHOWS ALL POSTS - NOT JUST THE MOST RECENT 4 STICKY ONES.
<?php
$sticky = get_option( 'sticky_posts' );
$args = array(
'posts_per_page' => 4,
'post__in' => $sticky,
'paged' => 1,
'ignore_sticky_posts' => 1
);
if (have_posts() ) { while ( have_posts() ) : the_post(); ?>
ALL OF MY OUTPUTTED CODE GOES HERE - EDITED OUT TO SAVE SPACE
<?php endwhile;?>
<?php } else { echo ""; }?>
<?php wp_reset_query(); ?>
Limit the number of posts you return in the query, not by slicing the array.
From http://codex.wordpress.org/Class_Reference/WP_Query#Post_.26_Page_Parameters
$sticky = get_option( 'sticky_posts' );
$args = array(
'posts_per_page' => 4,
'post__in' => $sticky,
'ignore_sticky_posts' => 1
);
Take a look at the Codex reference above for examples of loops. Here's the gist of what you need.
// The Query
$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();
Notice how the new WP_Query accepts the args from above. In the code you posted you weren't doing anything with them.