Why isn't this Wordpress query sorting properly - wordpress

I have a custom post_type called special_listing which contains a custom field called listing_index. A special_listing with a listing_index of 20, should appear before one with an index of 15, then 10, and so on. However this doesn't appear to be working and listings appear in whatever order they choose.
I'm not a PHP or Wordpress guy, I mainly deal with ASP.Net and C# so this is a bit confusing for me. Is there some simple mistake I'm making?
Function:
// Get the first $count listings with the highest indices for a given $region_slug:
function get_listings($region_slug, $count) {
$args = array(
'post_type' => 'special_listing',
'meta_key' => 'listing_region_slug',
'meta_value' => $region_slug
);
$posts = get_posts($args);
sort_array_on_field($posts, 'listing_index', 'DESC');
truncate_array($posts, $count);
return $posts;
}
View:
<?php
$listings = get_listings(get_microsite_slug() . '-microsite-home-featured', 4);
$i = 0;
if (sizeof($listings) > 0) : while ($i < sizeof($listings)) : $listing = $listings[$i]; // Loop and set current listing
?>
<section>
<a href="<?php echo $listing->destination; ?>">
<h3><?php echo $listing->post_title; ?></h3>
<p><?php echo $listing->post_content; ?></p>
</a>
</section>
<?php $i++; ?>
<?php endwhile; ?>
<?php endif; ?>
My attempt:
I don't know how to return the listing_index value
function get_sorted_listings($region_slug, $count){
$args = array(
'post_type' => 'kodakalaris_listing',
'meta_query' => array(
'relation' => 'AND',
array (
'key' => 'listing_region_slug',
'value' => $region_slug
),
array (
'key' => 'listing_index',
'value' => ''
),
orderby: 'listing_index',
order: 'DESC'
)
);
$posts = get_posts($args);
truncate_array($posts, $count);
return $posts;
}
Update
Trying a new way and it now pulls the content in by the published date. Still not ordering by listing_index, but at least it's not completely random either. I began looking to meta_query. Won't this only return a result with a single value? I've also tried out this other SO answer, but I find it's implementation confusing.
<?php
$args = array(
'post_type' => 'kodakalaris_listing',
'meta_key' => 'listing_region_slug',
'meta_value' => get_microsite_slug() . '-microsite-home-featured',
'posts_per_page' => 4,
'order' => 'DESC',
'orderby' => 'listing_index'
);
$listings = new WP_Query($args);
if ($listings->have_posts()) : while ($listings->have_posts()) : $listings->the_post();
?>
...
...
<?php
endwhile;
endif;
?>

You don't need to sort after you query. WP_Query has orderby parameters:
function get_listings($region_slug, $count) {
$args = array(
'post_type' => 'special_listing',
'meta_key' => 'listing_region_slug',
'meta_value' => $region_slug,
'orderby' => 'meta_value_num'
);
$posts = new WP_Query($args);
return $posts;
}
You'll then want to use The Loop rather than a foreach loop, in your view.

So I was able to figure this out after reading this article, but basically assigning a name to each meta_query array allows you to call which one should take priority when using orderby.
$args = array(
'post_type' => 'special_listing',
'posts_per_page' => 4,
'orderby' => 'index_clause',
'meta_query' => array (
'site_clause' => array (
'key' => 'listing_region_slug',
'value' => get_microsite_slug() . '-microsite-home-featured'
),
'index_clause' => array (
'key' => 'listing_index',
)
)
);

Change the function to :
<?php
// Get the first $count listings with the highest indices for a given $region_slug:
function get_listings($region_slug, $count) {
$args = array(
'post_type' => 'special_listing',
'orderby' => 'listing_index',
'order' => 'DESC',
'meta_key' => 'listing_region_slug',
'meta_value' => $region_slug
);
$posts = get_posts($args);
return $posts;
}

Related

Only display upcoming events in Wordpress Widget

Through a shortcode I placed the following code which is intented to display a random upcoming event in the sidebar. At the moment it displays a random of ALL events. How would I change the code to only display events that are younger than the current date?
<?php
// Build a custom query to get posts from future dates.
$querystr = `
SELECT wposts.*
FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta
WHERE wposts.ID = wpostmeta.post_id
AND wpostmeta.meta_key = 'f21_event_startdate'
AND STR_TO_DATE(wpostmeta.meta_value,'j. M Y') >= CURDATE()
AND wposts.post_status = 'publish'
AND wposts.post_type = 'events'
ORDER BY STR_TO_DATE(wpostmeta.meta_value,'j. M Y') RAND
LIMIT 1
`;
$events = $wpdb->get_results($querystr, OBJECT);
if ($events):
global $post;
foreach ($events as $post):
setup_postdata($post); ?>
<?php the_field('f21_event_startdate'); ?>
<h2><a style="color:#1e73be;" href="<?php the_permalink() ?>"><?php the_title(); ?></h2>
<div style="margin-top:10px; margin-bottom: 10px;"><?php the_post_thumbnail('full'); ?></div></a>
<b><?php the_field('f21_event_sub_header'); ?></b>
<?php endforeach;
else : ?>
<li>Sorry, no events coming up.</li>
<?php endif; ?>
you can WP_Query(). check the code below.
$args = array(
'post_type' => 'events',
'posts_per_page' => -1,
'meta_key' => 'f21_event_startdate',
'meta_value' => date('Ymd'),
'meta_compare' => '>=',
'orderby' => 'rand',
'order' => 'ASC'
);
$upcoming_events = new WP_Query( $args );
Avoid the SQL query in WordPress for getting post-type data.
we have a function for that please use
$args = array(
'post_type' => 'tribe_events',
'post_status' => 'publish',
'posts_per_page' => 10,
'order' => 'ASC',
'orderby' => 'meta_value',
'meta_key' => '_EventStartDate',
'meta_type' => 'DATETIME',
'paged'=>$page,
'meta_query'=>array(
array(
'key' => '_EventStartDate',
'value' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ),
'compare' => '>'
),),
'tax_query'=>array(array(
'taxonomy' => 'tribe_events_cat',
'field' => 'id',
'terms' =>$tribe_events_cat,
))
);
$events = new WP_Query($args);
Summary: if you are using custom fields in WordPress make sure your custom fields are stored as a post meta then you can easily filter that,
In the above code, we have a meta query where we can use key, value, and compare. thanks.

How to query custom post tye from specific category

i need to display post from a custom post type but from one specific category, i use the code belowe but show me all post from all categories not just from 7.
<?php
$args = array( 'post_type' => 'tour', 'posts_per_page' => 10, 'cat=7' , 'taxonomy' => 'tourcat');
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
echo "TEST TEST TEST TEST";
echo the_title();
echo '<div class="entry-content">';
the_content();
echo '</div>';
endwhile;
?>
This is not a valid argument for WP Query.
cat=7
Please read here about taxonomy queries, they should do what you require:
https://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters
Currently your $args array simply holds an element that is cat=7, which is an incorrect way to pass arguments to the WP_Query constructor. Note that the issue is a little more obvious if you format your $args array with whitespace:
$args = array(
'post_type' => 'tour',
'posts_per_page' => 10,
'cat=7' , /* Here is the problem */
'taxonomy' => 'tourcat'
);
I believe your $args array should look like the following:
$args = array(
'post_type' => 'tour',
'posts_per_page' => 10,
'cat' => 7,
'taxonomy' => 'tourcat'
);
This,
$args = array( 'post_type' => 'tour', 'posts_per_page' => 10, 'cat=7' , 'taxonomy' => 'tourcat');
Should instead be like,
$args = array( 'post_type' => 'tour', 'posts_per_page' => 10, 'tax_query' => array( array( 'taxonomy' => 'tourcat','field' => 'ID','terms' => '7' ) ));
Try this :
$postData = new WP_Query(array(
'post_type' => 'tour', // custom post type
'posts_per_page'=>10,
'tax_query' => array(
array(
'taxonomy' => 'tourcat', //custom taxonomy name
'field' => 'id',
'terms' => 7
)
)
));
if($postData->have_posts()):
while ($postData->have_posts()): $postData->the_post();
echo "TEST TEST TEST TEST";
the_title();
echo '<div class="entry-content">';
the_content();
echo '</div>';
endwhile;
endif;

Exclude parent posts and display only child posts in archive

I have done this query and is working.I have a lot of child posts and i plan to display only child posts when listing the archive page of my custom post type city-guide.
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'city-guide',
'posts_per_page' => 36,
'paged' => $paged
);
$query = new WP_Query( $args );
?>
<?php $i=1; while( $query->have_posts() ): $query->the_post(); ?>
{
.....
}
I have tried
$all = get_posts(array('post_type'=> 'city-guide', 'posts_per_page' => -1));
$parents = array();
foreach ($all as $single)
{
$kids = get_children($single->ID);
if(isset($kids) && !empty($kids) && count($kids) >= 1)
{
$parents[] = $single->ID;
}
}
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'city-guide',
'post__not_in' => $parents,
'posts_per_page' => 36,
'paged' => $paged
);
$query = new WP_Query( $args );
?>
<?php $i=1; while( $query->have_posts() ): $query->the_post(); ?>
{
....
}
This did not work.Please help me find out where i went wrong.
I know it's an old question but hoping I can help someone that finds their way here looking for the same thing I was.
You can show ONLY child posts by excluding any posts with post_parent = 0 using the 'post_parent__not_in' argument:
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'city-guide',
'posts_per_page' => 36,
'paged' => $paged,
'post_parent__not_in' => array(0)
);
This avoids the need to loop thru each parent post to get each child.
I see you are trying to push the IDs into an array but why not just use the IDs while you are looping through them while getting the children within the loop at the same time? The example below is how I would tackle this.
<?php
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'city-guide',
'posts_per_page' => 36,
'paged' => $paged
);
$query = new WP_Query( $args );
$i=1; while( $query->have_posts() ): $query->the_post();
$parentID = get_the_ID();
$childrenArgs = array(
'post_type' => 'page',
'post_parent' => $parentID ,
);
$children = get_children($childrenArgs);
foreach ($children as $child){
echo '<h1>' . $child -> post_title . '</h1>';
$content = $child -> post_content;
$content = apply_filters('the_content', $content);
$content = str_replace(']]>', ']]>', $content);
echo $content;
}
endwhile;
?>
I think you need to look into the action pre_get_posts. Something like this in your functions.php would do the trick.
function namespace_custom_query_vars( $query ) {
if ( !is_admin() && $query->is_main_query()) {
if ( $query->query["post_type"] == 'custom_post_type' ) {
$query->set( 'post_parent__not_in', 0 );
}
}
return $query;
}
add_action( 'pre_get_posts', 'namespace_custom_query_vars' );
There's a decent post about this here. Though note that the code on this page does not compile for small syntax errors.
What about using relations? A simple disjunctive union should do the charm.
$args = array(
'post_type' => POST_TYPE,
'posts_per_page' => 36,
'orderby' => 'date',
'order' => 'DESC',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => POST_TAXONOMY,
'field' => 'slug',
'terms' => $tax_slug,
'include_children' => true
),
array(
'taxonomy' => POST_TAXONOMY,
'field' => 'slug',
'terms' => $tax_slug,
'include_children' => false,
'operator' => 'NOT IN'
)
)
);
Or is there a reason why not to consider this?

Exclude duplicated posts from wordpress custom queries

I'm building a template for a homepage which shows 4 latest posts on top and some groups of posts divided by category around the page (I'm using get_posts to perform queries).
What I'd like to do is exclude from these category posts any post already present in the latest four news on top.
I guess I should get that four post IDs and use the 'post__not_in' parameter in the "category" queries, but I can't make it work.
Dou you have any hints?
This is the code:
// First query: I get last four posts
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'numberposts' => 4
);
// In my dreams, this should be the array of post IDs
$ids->query_vars['page_id'];
// Second query: I get 5 posts for a given categoory and exclude posts with IDs from first query
$query = new WP_Query($args);
$args2 = array(
'numberposts' => 5,
'category' => 15,
'orderby' => 'post_date',
'order' => 'DESC',
'post__not_in' => $ids
);
$query2 = new WP_Query($args2);
$primaposizione = get_posts( $args2 );
foreach ( $primaposizione as $post ) : setup_postdata( $post );
... do the stuff ...
endforeach;
wp_reset_postdata();
UPDATE
<?php
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'orderby' => 'post_date',
'order' => 'DESC',
'posts_per_page' => 4
);
$query = new WP_Query($args);
$excludeID = array();
while ( $query->have_posts() ) : $query->the_post();
$excludeID = $post->ID;
endwhile;
$args = array(
'posts_per_page' => 1,
'orderby' => 'post_date',
'order' => 'DESC',
'category' => 15,
'post_type' => 'post',
'post_status' => 'publish',
'post__not_in' => array($excludeID)
);
$primaposizione = get_posts( $args );
foreach ( $primaposizione as $post ) : setup_postdata( $post );
$category = get_the_category();
$slug = $category[0]->category_nicename ;
$esteso = $category[0]->cat_name;
if(has_post_thumbnail()) { ?>
<span class="hidden-xs"><?php the_post_thumbnail('bones-thumb-300', array('class' => 'img-responsive')) ?></span>
<?php } ?>
<h3 class="ellipsis"><?php the_title(); ?></h3>
<?php the_excerpt();?>
<?php endforeach;
wp_reset_postdata();
?>
The way you're trying to select the ID's is not going to work. You have to call wp_query first. I think this should work:
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'numberposts' => 4
);
$query = new WP_Query($args);
$excludeID = array();
while ( $query->have_posts() ) : $query->the_post(); ?>
$excludeID[] = $post->ID; // forgot the brackets
// do stuff
endwhile;
(...)

wordpress advanced custom fields order posts by date-picker

For those familiar with the ACF plugin...
I have some events posts that are currently displaying in post order (see code below). I would like them to display in the order specified by the date-picker.
Can anyone tell me what to amend in the following - I have tried the documentation on the site, but my PHP is basic.
It says I need to add
'orderby' => 'meta_value_num',
But no joy.
<?php function le_whatson_aside() {
//THis loop is for the CPT
$args = array(
'post_type' => 'events', // enter your custom post type
'orderby' => 'menu_order',
'order' => 'ASC',
'posts_per_page'=> '10', // overrides posts per page in theme settings
'tax_query' => array(
array(
'taxonomy' => 'audience', //name of custom taxonomy
'field' => 'slug',
'terms' => 'everyone' //name of category
)
)
);
$loop = new WP_Query( $args );
if( $loop->have_posts() ):
?>
<div>
<h2>What's On</h2>
</div>
<div class="whatson entry-content">
<?php
while( $loop->have_posts() ): $loop->the_post(); global $post;
?>
<p class="whatson-date"><?php echo date("dS F Y",strtotime(get_field('date')));?></p>
<h4 class="whatson-title"><?php echo get_the_title(); ?></h4>
<?php
endwhile;
?>
</div>
<?php
endif; }
Thanks all.
Try
orderby=date or `post_date`
If not the easiest way is to save your custom field 'startdate' as a unix timestamp. To do this, add the following to your theme's functions.php
// CREATE UNIX TIME STAMP FROM DATE PICKER
function custom_unixtimesamp ( $post_id ) {
if ( get_post_type( $post_id ) == 'events' ) {
$startdate = get_post_meta($post_id, 'startdate', true);
if($startdate) {
$dateparts = explode('/', $startdate);
$newdate1 = strtotime(date('d.m.Y H:i:s', strtotime($dateparts[1].'/'.$dateparts[0].'/'.$dateparts[2])));
update_post_meta($post_id, 'unixstartdate', $newdate1 );
}
}
}
add_action( 'save_post', 'custom_unixtimesamp', 100, 2);
The do:
$today = time();
$args = array(
'post_type' => 'events',
'posts_per_page' => 5,
'meta_query' => array(
array(
'key' => 'unixstartdate',
'compare' => '>=',
'value' => $today,
)
),
'meta_key' => 'startdate',
'orderby' => 'meta_value',
'order' => 'ASC',
);
$query = new WP_Query( $args );
$events = $query->posts;
Got it from here
I spent hours looking for this and I can confirm it works. See my code below.
If you're trying for a loop on a page with other loops, with a bunch of template parts in there, and you would also like to sort by a category, it goes :
$today = time();
$the_query = new WP_Query( array(
'post_type' => 'events',
'posts_per_page' => 3,
'meta_query' => array(
array(
'key' => 'start',
'value' => $today,
'compare' => '>=',
)
),
'tax_query' => array(
array (
'taxonomy' => 'the_taxonomy',
'field' => 'slug',
'terms' => 'the-name'
)
),
'meta_key' => 'start',
'orderby' => 'meta_value',
'order' => 'ASC',
) );
while ( $the_query->have_posts() ) :
$the_query->the_post();
get_template_part( 'content-events' );
endwhile;
wp_reset_postdata();
Of course, you have to include Unix the function beforehand.
function custom_unixtimesamp ( $post_id ) {
if ( get_post_type( $post_id ) == 'events' ) {
$startdate = get_post_meta($post_id, 'start', true);
if($startdate) {
$dateparts = explode('_', $startdate);
$newdate1 = strtotime(date('d.m.Y H:i:s', strtotime($dateparts[1].'/'.$dateparts[0].'/'.$dateparts[2])));
update_post_meta($post_id, 'unixstartdate', $newdate1 );
}
}
}
add_action( 'save_post', 'custom_unixtimesamp', 100, 2);
I would approach it like this. Create a "named" meta query and then order by that query. The meta query uses "EXITS" to filter out posts that don't have a date set. This works with the ACF date picker when the dates are saved to the database using the default format d/m/Y. This approach also works with the datetime picker.
$query = new WP_Query([
"meta_query" => [
"custom_date" => [
"key" => "date",
"compare" => "EXISTS",
"type" => "DATETIME",
]
],
"orderby" => [
"custom_date" => "ASC",
],
]);
Be sure to update the value for key to whatever your ACF field name is.

Resources