I've written this loop to pull in posts that get the most views within the last 30 days (logging the view count to the DB as a custom meta key).
Though, upon thinking about it a little more I'm not really sure if I'm going about it the 'right' way, or at least the most logical way.
<?php
// Create a new filtering function that will add our where clause to the query
function filter_where( $where = '' ) {
// posts in the last 30 days
$where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
return $where;
}
add_filter( 'posts_where', 'filter_where' );
$popularpost = new WP_Query( array(
'posts_per_page' => 33,
'meta_key' => 'wpb_post_views_count',
'orderby' => 'meta_value_num',
'order' => 'DESC'
) );
remove_filter( 'posts_where', 'filter_where' ); ?>
<?php if ( $popularpost->have_posts() ) : ?>
<?php while ( $popularpost->have_posts() ) : $popularpost->the_post(); ?>
<article <?php post_class('item-post block'); ?> id="post-<?php the_ID(); ?>">
<?php the_title (); ?>
</article> <!-- end div post -->
<?php endwhile; wp_reset_query(); ?>
<?php endif; ?>
So, as you can see I'm limiting the date range to 30 days, ordering the posts by the meta_value_num and getting 33 posts.
So, logically what's happening is any post published within the last 30 days will be displayed here in order of how many views they've had.
What got me thinking about it is when I created a page to pull the 33 most viewed posts from the last 7 days, they're the same. Obviously.
So I think what I want to be doing is getting posts by how many views they've had IN the last 30 days/7 days, not posts published within those date ranges.
Am I thinking along the right lines? If so, can you give me any idea of how to go about that?
If you're running the WordPress 3.7 or later, you now can use date_query. Not tested, but your query will look something like:
$popularpost = new WP_Query( array(
'posts_per_page' => 33,
'meta_key' => 'wpb_post_views_count',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'date_query' => array(
array(
'after' => '1 month ago',
'column' => 'post_date_gmt', //posted within one month
),
)
)
);
$where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
strtotime('30 days') = now + 30 days
Related
As the title says, in the homepage (index.php) I want to add a section for the news which is populated by "news" tagged posts and it only shows posts from the last 30 days. if no posts has been published in the last 30 days then the news section is empty and disappears.
how do I query those posts from last 30 days? do I use a new WP_query or pre_get_posts?
how do I write it to make the section not show up if there are no news?
I'm guessing it's enough to create the div inside the loop instead of outside using
if ( have_posts() ) :
echo '<div class="newsdiv">','<ul>'
while ( have_posts() ) : the_post('<li>','</li>');
// Display post content
the_title('<h2 class="news">','</h2>');
the_thumbnail();
the_excerpt();
endwhile;
echo '</ul>','</div>'
endif;
?>
i'm sorry for banal questions or mistakes, i'm trying to learn wordpress and php. If you could add some explanation with your answer it would make it easier for me to learn the why and not just how.
Using WP_Query add next params:
$args= array(
'date_query' => array(
array(
'after' => '-30 days',
'column' => 'post_date',
),
),
);
$your_query = new WP_Query($args);
It will grab posts post_type => 'post' for the last 30 days
if($your_query->have_posts()) :
// Code to display your news
while($your_query->have_posts()) : $your_query->the_post();
// Single news
endwhile; wp_reset_postdata();
else:
// No posts
endif;
Using WP_Query like this:
$args = array(
'post_type' => 'posts',
'posts_per_page' => 20,
'date_query' => array(
array(
'after' => '-30 days',
'column' => 'post_date',
),
),
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) :
while ( $loop->have_posts() ) : $loop->the_post();
// add your loop content here
endwhile;
wp_reset_postdata();
// Reset query incase we want to use another query on the same page
endif;
I am having trouble with a custom Wordpress / ACF loop I am working on.
The idea is that it displays the latest posts within the 'events' post type, hiding any posts where the event date has passed.
The posts do hide if the date has passed. However the loop is not displaying the full amount of posts available. Currently with the loop below, it is only showing 6 out of the available 10.
I have checked the reading settings in Wordpress and that's fine.
The code I am using for my loop is:
<ul class="events-list">
<?php
$loop = new WP_Query( array(
'post_type' => 'events',
'posts_per_page' => -1,
'orderby' => 'meta_value',
'order' => 'ASC',
'meta_type' => 'DATE',
'meta_key' => 'event-date'
));
while ( $loop->have_posts() ) : $loop->the_post();
$today = date('dmY');
$expire = get_field('event-date');
if( $expire > $today )
{ ?>
<li>
<h3><?php the_field('event-date'); ?> - <?php the_title(); ?></h3>
<span class="time"><?php the_field('event-time'); ?></span>
<?php the_field('event-details'); ?>
</li>
<?php; } endwhile; wp_reset_query(); ?>
</ul>
If you're going to compare dates then you need to convert them to the appropriate types. Convert them to Unix timestamp then you can easily compare when the date has surpassed. At the moment you are comparing which string is greater than the other which works sometimes but it's much more reliable to use Unix timestamp as your date formats always need to match.
if(strtotime(get_field('event-date')) > date('U')) {
//Your code here
}
Simply print compared dates before the "if" statement, and you will see where you made a mistake.
echo $expire.'__'.$today.'<br>';
if( $expire > $today )
It can be because of invalid date format, empty $expire field etc.. Anyway, you will see what the reason is after implementing that print.
The solution to this problem was to change the loop to:
<?php
$today = date('Ymd');
$loop = new WP_Query( array(
'post_type' => 'events',
'showposts' => 2,
'meta_key' => 'event-date',
'meta_compare' => '>',
'meta_value' => date("Ymd"),
'orderby' => 'meta_value_num',
'order' => 'ASC'
));
while ( $loop->have_posts() ) : $loop->the_post();
{ ?>
Post stuff here
<?php; } endwhile; wp_reset_query(); ?>
I am trying to display most commented posts of certain category last month.
This is my code for now, I cant figure out what is wrong here, any ideas?
<?php
function filter_where( $where = '' ) {
$where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
return $where;
}
add_filter( 'posts_where', 'filter_where' );
$the_query = new WP_Query(array( 'posts_per_page' => 3, 'cat' => 2, 'orderby' => 'comment_count date', 'order'=> 'DESC' ));
remove_filter( 'posts_where', 'filter_where' );
?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post();
echo get_the_title();
// and rest of content
endwhile;
wp_reset_postdata(); ?>
edit: p.s. btw I am using Vkontakte Api plugin for my comments. May be the problem is here, because this code actually works fine on other site. But, get_comments_number() shows the correct number, why then orderby => comment_count doesnt work?
You have to use date_query, for this.
$args = [
'posts_per_page' => 3,
'post_type' => 'post',
'date_query' => [
[
'year' => date('Y', strtotime(date('Y-m-d') . " -1 month")),
'month' => date('m', strtotime(date('Y-m-d') . " -1 month"))
]
],
'orderby' => 'comment_count',
'order' => 'DESC'
];
$posts = new WP_Query($args);
//$posts = get_posts($args);
//print_r($posts);
The MySQL query will be for getting the popular post of last month will be: (assuming NOW() = 13 Feb 2017)
SELECT
posts.ID,
posts.post_title,
posts.post_date
FROM
wp_posts AS posts
WHERE
YEAR (posts.post_date) = 2017
AND MONTH (posts.post_date) = 1
AND posts.post_type = 'post'
AND posts.post_status = 'publish'
ORDER BY
posts.comment_count DESC
LIMIT 0, 3;
Hope this helps!
I need to have 5 random posts on post page (http://7cuteoutfits.com/2015/07/08/suits-rachel-z-office-fashion/) excluding current post. Random posts should be on chosen dates (for example posts from last 2 months until yesterday )
I added a few lines of code to single.php of my wordpress and now have 5 random posts. So I need to modify the code so that it will meet my requirements (above). I think it's 2 more lines, I'll be very thankful if you help.
<ul>
<?php
$currentID = get_the_ID();
$args = array( 'posts_per_page' => 5, 'orderby' => 'rand' );
$rand_posts = get_posts( $args);
foreach ( $rand_posts as $post ) :
setup_postdata( $post ); ?>
<li><?php the_title(); ?></li>
<?php endforeach;
wp_reset_postdata(); ?>
</ul>
You can use WP_Query for that.
global $post;
$args = array(
'post__not_in' => array($post->ID)
'orderby' => 'rand'
'date_query' => array(
array(
'after' => 'January 1st, 2015',
'before' => array(
'year' => 2015,
'month' => 07,
'day' => 9,
),
'inclusive' => true,
),
),
'posts_per_page' => 5,
);
$query = new WP_Query( $args );
This query orders randomly posts between today (inclusive) and Jan. 1st 2015
I haven't tested the snippet here, so please let me know if it does not work for you.
More info on WP_query and its usage (also for date parameters) here
Once you query with WP_Query, you have to
wp_reset_postdata();
just as you are already doing.
EDIT:
To show the post content, you can call
the_content()
to print it directly, or
get_the_content()
to get it as a return value. Then you can handle the printing later with the HTML markup you desire.
I'm using the following custom query in Wordpress within a for-loop that enables me to create a tabbed archive for the previous 8 months of the custom post type I've created for 'news'.
This works perfectly however I wish to then show every older post under the heading 'Older news. I'm struggling to figure out how to separate the posts that are older than 8 months from the current date at any one time.
Can anyone advise me as to a custom query structure that would enable me to do this.
Here's the code i use to output the CPTs in their relevant containers.
<?php for($i = $this_month-1; $i > $this_month-8; $i--) :
if($i==-1){$m=11;}
if($i==-2){$m=10;}
if($i==-3){$m=9;}
if($i==-4){$m=8;}
if($i==-5){$m=7;}
if($i==-6){$m=6;}
if($i==-7){$m=5;}
if($i==-8){$m=4;}
else{$m=$i;}
query_posts( array(
'post_type' => 'news',
'posts_per_page' => '-1',
'orderby' => 'date',
'order' => 'ASC',
'monthnum'=>$m
) );
.......
You may try this
<?php
add_filter('posts_where', 'filter_where');
query_posts( array('post_type' => 'news', 'posts_per_page' => '-1', 'orderby' => 'date'));
function filter_where($where = ''){
$where .= " AND post_date < '".date('Y-m-d', strtotime('-8 month'))."'";
return $where;
}
remove_filter('posts_where', 'filter_where');
if (have_posts()) :
while (have_posts()) : the_post();
// your code
endwhile;
endif;
wp_reset_query();
?>
Update: May be this can help you.
$args = array(
'post_type' => 'news',
'posts_per_page' => '-1',
'orderby' => 'date',
'year' => date('Y'), // for current year, date('Y')-1 for 1 year ago
'monthnum' => $m, // the month in the loop
'order' => 'ASC'
);
query_posts( $args );
I am not much aware of wordpress but can help you logically. As per my knowledge, This can be done by checking condition like "WHERE creation_date < 8 months" in your query while retriving posts for category 'older news'. So first get current date.
<?php $today = date('Y-m-d'); ?>
Then subtract 8 months from it and you will get a date 8 month older
<?php $eight_month = date('Y-m-d',strtotime("-8 month $today")); ?>
now you can use $eight_month in your query so your query would be something like this. Check format of date you are storing in your database for post and change my accordingly if it is different than format "Y-m-d"
"SELECT * FROM posts WHERE creation_date < '$eight_month'"
Hope this is what you want and help you in your project. Best luck and have a nice day