How to query on custom fields in Wordpress? - wordpress

I'm trying to query posts based on a custom field, and then display them in a loop. I've checked and double checked my code against the codex and other sources, but the query still does not appear to be working. What am I doing wrong?
Stripped down to the essentials, my code looks like this:
<?php
$args = array(
'meta_key' => 'my_custom_field'
);
$my_query = new WP_Query( $args );
?>
<?php if ( $my_query->have_posts() ) { ?>
<p>Success, we have posts!!!</p>
<?php } else { ?>
<p>Uh Oh, No posts!!!</p>
<?php } ?>
The conditional statement is dropping through and returning "Uh Oh, no posts".
I've checked the postmeta table, and there are definitely posts that contain the meta_key _my_custom_field. I have tried the query both with and without leading underscore.
What am I doing wrong?

I use this for search a date between two custom dates field in my custom post type "porfolio", i think that you are in a similar situation:
$args = array(
'post_type' => 'portfolio',
'posts_per_page' => '10',
'meta_query' => array(
array('key' => 'portfolio_start_date', 'value' => data_to_db2($ricerca_data), 'compare' => '<=', 'type' => 'NUMERIC'),
array('key' => 'portfolio_end_date', 'value' => data_to_db2($ricerca_data), 'compare' => '>=', 'type' => 'NUMERIC')
)
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
$post_count = wp_count_posts();
while ( $the_query->have_posts() ) {
// DO WHAT YOU WANT
}
}
My advice is to use meta_query in $args array

Related

Query only custom fields with wordpress

I am executing the following WP_Query on my mysql database:
$products = new WP_Query(array(
'post_type' => 'posts',
'meta_query' => array(
array(
'key' => 'meta_key',
'compare' => '=',
'value' => '_cegg_data_Amazon',
),
),
));
When I var_dump($product) I am receiving a long wp_Query object. However, I would only like to receive an object/list of the custom post fields. The below SQL query gives me exactly that back within phpmyadmin:
SELECT * FROM `wp_postmeta` where meta_key="_cegg_data_Amazon" ORDER BY `wp_postmeta`.`meta_key` ASC
Any suggestions how to get only the values of the custom fields _cegg_data_Amazon. I appreciate your replies!
I think the easiest way would be to loop through your WP_Query object and create your array (or new obj) with the desired field:
$products = new WP_Query(array(
'post_type' => 'posts',
'meta_query' => array(
array(
'key' => 'meta_key',
'compare' => '=',
'value' => '_cegg_data_Amazon',
),
),
));
$cegg_data = array(); // initiate the new array
if( $products->have_posts() ) :
while( $products->have_posts() ) : $products->the_post();
$cegg_data[] = get_post_meta(get_the_ID(), '_cegg_data_Amazon', true); // populate array with the new value
endwhile;
endif;
wp_reset_query();
Now, if you var_dump "$cegg_data" it should contain an indexed array with the custom field values.
NB: the code is untested, just a quick draft ;)
Another and solution you can explore would be "posts_fields" filter documented here: https://developer.wordpress.org/reference/hooks/posts_fields/
Hope this helps and good luck ;)
Francesco

Why isn't this Wordpress query sorting properly

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;
}

Custom Taxonomy Filtering with Wordpress

Ive been trying to figure this out for three days now, even using solutions on this site. I still cant get this working.
I have a wordpress loop that uses a filter to show posts by post type. Now the post type is called "case-studies" Thus all the posts in the type case studies are shown.
But i need to hide a specific taxonomy term from this loop. The taxonomy is called "sectors" and the term is "healthcare". Ive tried all manner of combinations but still cant get this. I need this pretty urgent. Anyone who can help would save my life.
Here is the query and the loop
<?php
// The Query
$the_query = new WP_Query( 'post_type=case-studies&posts_per_page=-1' );
// The Loop
while ( $the_query->have_posts() ) :
$the_query->the_post();
?>
$args = array(
'post_type' => 'case-studies',
'tax_query' => array(
array(
'taxonomy' => 'sectors',
'field' => 'slug',
'terms' => array('comercial', 'personal', 'etc') //excluding the term you dont want.
)
)
);
$query = new WP_Query( $args );
I dind´t try it but you could just make a query calling only the terms you want, you could previously populate the terms array listing all the terms on the taxonomy and excluding the one you want, i think this is a little hacky it should be another straight forward way to do it but give it a try since it is a case of life or dead =).
source: http://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters
Try this one:
<?php
$type = 'cpreviews';
$args=array(
'post_type' => $type,
'post_status' => 'publish',
'posts_per_page' => -1,
'caller_get_posts'=> 1
);
$my_query = null;
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) {
while ($my_query->have_posts()) : $my_query->the_post(); ?>
<p><?php the_title(); ?></p>
<?php
endwhile;
}
wp_reset_query(); // Restore global post data stomped by the_post().
?>
ok then try this one it will extract your terms dinamicaly and exclude the term you dont want, i didn´t check if it is working but this is the logic, please check for sintax errors.
$terms = get_terms("sectors");
$count = count($terms);
$termsAr = array();
if ($count > 0 ){
foreach ( $terms as $term ) {
if($term->name !== "healthcare"){//Here we exclude the term or terms we dont want to show
array_push($termsAr, $term->name);
}
}
}
$terms = get_terms("types");
$count = count($terms);
$termsAr2 = array();
if ($count > 0 ){
foreach ( $terms as $term ) {
if($term->name !== "healthcare"){//Here we exclude the term or terms we dont want to show
array_push($termsAr2, $term->name);
}
}
}
$args = array(
'post_type' => 'case-studies',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'sectors',
'field' => 'slug',
'terms' => $termsAr //excluding the term you dont want.
),
array(
'taxonomy' => 'types',
'field' => 'slug',
'terms' => $termsAr2 //excluding the term you dont want.
)
)
);
$query = new WP_Query( $args );

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.

Exclude a featured post from the Wordpress loop

My Wordpress front page has both a featured article (styled inside a box) and a list of recent posts (styled separately). I want to display these recent posts using Wordpress loop excluding the featured post. It is easy to achieve excluding a certain category or a tag, but in my case I want to exclude a post with a custom field. The featured post has a custom field with a name and a value of: featured = yes.
How do I achieve this without using a plugin?
You can use meta_query parameter, as explained in http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters
Something like:
$args = array(
'post_type' => 'any',
'meta_query' => array(
array(
'key' => 'featured',
'value' => 'yes',
'compare' => 'NOT LIKE'
)
)
);
$query = new WP_Query( $args );
$args = array(
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'featured',
'value' => 'yes',
'compare' => '='
),
));
$ids = array();
$query = new WP_Query($args); // fetching posts having featured = yes
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
$ids[] = $post->ID; // building array of post ids
}
}
$args = array( 'post__not_in' =>$ids); // excluding featured posts from loop
query_posts($args);
while (have_posts()) : the_post();
// rest of the code

Resources