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
Related
I have a custom post type of post_type_1 in WordPress, I also have a custom field in that post type of custom_field_data
I am doing a search for apples by querying posts using wp_query like this...
$search_term = 'apples';
$args = array(
'post_type' => array('post_type_1'),
'post_status' => array('publish'),
'posts_per_page' => -1,
's' => sanitize_text_field( $search_term)
);
$results= new WP_Query( $args );
This works correctly and returns all posts with apples in the title, but I would also like to extend the search to the custom field custom_field_data so the query will return all posts with apples in either title or custom field.
What is my best approach? I have tried using a meta_query but haven't been successful. Does anybody have an example?
Use below code will work for custom field search.
$custom_field = $_GET['custom_field '] != '' ? $_GET['custom_field '] : '';
$search_term = 'apples';
$args = array(
'post_type' => array('post_type_1'),
'post_status' => array('publish'),
'posts_per_page' => -1,
's' => sanitize_text_field( $search_term),
'meta_query' => array(
array(
'key' => 'custom_field_key',
'value' => $custom_field ,
'compare' => 'LIKE',
),
)
);
$results= new WP_Query( $args );
Tested and works well.
I'm currently working on a query where I show only posts without empty featured image using this:
$args = array(
'meta_query' => array(
array( 'key' => '_thumbnail_id')
)
);
Everything is working great. But I have some video format posts without featured images that I would like to return with that query.
Is that even possible with WP_Query?
Any help would be great!
Got it to work with 2 WP_Query and a array_merge, not sure if it's the best way to go but does the work.
If that can help:
get posts with thumb
$args = array(
'meta_query' => array(
array( 'key' => '_thumbnail_id'), //Show only posts with featured images
)
);
$posts_with_thumb = new WP_Query($args);
get video posts format
$args = array(
'tax_query' => array(
array(
'taxonomy' => 'post_format',
'field' => 'slug',
'terms' => array( 'post-format-video' ),
),
)
);
$posts_video_format = new WP_Query($args);
init new wp_query object and merge both results
$featured_query = new WP_Query();
$featured_query->posts = array_merge( $posts_with_thumb->posts, $posts_video_format->posts );
I need to create a products archive page (usually the Shop page in WooCommerce) but displays ONLY the ON SALE products. Basically it should use the same template layout as that in the archive-product.php. There will be a link in the main menu that will direct to this page. How do I go about this?
UPDATE
I managed to filter out the ON SALE products with the code below placed just above the if ( have_posts() ) : line...
$args = array(
'post_type' => 'product',
'order' => 'ASC',
'paged' => $paged,
'meta_query' => array(
array(
'key' => '_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
)
);
query_posts( $args );
The code is placed in a copy of archive-product.php which I named archive-product_sale.php and made as a page template.
However, this only works for Simple products type and I need it to work for both Simple products and Variable products type.
#mirus' answer regarding the shortcode gave me the idea to check out how WooCommerce is querying only the on-sale items. Apparently WooCommerce has a wc_get_product_ids_on_sale() function that will return the IDs of the on-sale items. Then we can easily adjust the query using the post__in parameter to only return those specific items.
WooCommerce has a woocommerce_product_query hook in the class-wc-query.php class that allows for us to modify the query before it is run.... it is run on pre_get_posts which is the usual place for modifying the query. Using Woo's hook just means you let them handle the majority of the conditional logic about when this query modification should be applied.
add_action( 'woocommerce_product_query', 'so_20990199_product_query' );
function so_20990199_product_query( $q ){
$product_ids_on_sale = wc_get_product_ids_on_sale();
$q->set( 'post__in', $product_ids_on_sale );
}
I managed to filter out the ON SALE products with the code below placed just above the if ( have_posts() ) : line...
$args = array(
'post_type' => 'product',
'meta_query' => array(
'relation' => 'OR',
array( // Simple products type
'key' => '_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
),
array( // Variable products type
'key' => '_min_variation_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
)
);
query_posts( $args );
The code is placed in a copy of archive-product.php which I renamed archive-product_sale.php and made as a page template.
#gmaggio using query_posts() will break your site.
Use pre_get_posts
add_filter( 'pre_get_posts', 'catalog_filters' );
function catalog_filters( $query ) {
if ( $query->is_main_query() && $query->post_type = 'product' ) {
if(isset($_GET['onsale'])) {
$meta_query = array(
'relation' => 'OR',
array( // Simple products type
'key' => '_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
),
array( // Variable products type
'key' => '_min_variation_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
); $query->set('meta_query', $meta_query);
}
if(isset($_GET['bestsellers'])) {
$meta_query = array(
array(
'key' => 'total_sales',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
);
}
}
return $query;
}
Create a new page using shortcode [sale_products per_page="12"]
List of available shortcodes and their parameters is here: http://docs.woothemes.com/document/woocommerce-shortcodes/
Solution for variable and simple products:
add_action( 'save_post_product', 'update_product_set_sale_cat_var' );
function update_product_set_sale_cat_var( $post_id ) {
$sales_ids = wc_get_product_ids_on_sale();
foreach ( $sales_ids as $sale_id ) :
if ($sale_id == $post_id) :
wp_set_object_terms($post_id, 'sale', 'product_cat', true );
else :
if ( has_term( 'sale', 'product_cat', $post_id ) ) {
wp_remove_object_terms( $post_id, 'sale', 'product_cat' );
}
endif;
endforeach;
}
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
Very simple setup, I'm using 1 template for multiple taxonomies. So example:
I have basic category + customtypetaxonomy. Both of them have terms. I'm displaying the posts of these terms in the same template - category.php. Which works great and how I want it.
However, I want to make small changes in this template based on the taxonomie it is getting its posts from. But I cannot figure out what function I need to use to get this.
For example: single_cat_title() gives me the title of the term (category)
But what I need is either the slug or the ID. Is there a way to do this? Something like single_cat_id or single_cat_slug. I have tried $cat but it doesn't give me any output.
Any ideas?
Use WP_Query. Like this:
$ThisQuery = new WP_Query( array( 'category_name' => 'MyCategory',
'meta_key' => 'MyCustomFieldValue',
'posts_per_page' => 10 ) ); // Number of posts
if ( $ThisQuery->have_posts() ) : while ( $ThisQuery->have_posts() ) : $ThisQuery->the_post();
...
endwhile;
endif;
wp_reset_postdata();
Modify the array to include the elements that identify the posts you want to fetch
Another EXAMPLE:
<?php
$Args = array( //Category
'cat' => 5, // Category id.
'category_name' => 'MyCategory', // Category Name.
//Taxonomy
'tax_query' => array( 'relation' => 'AND', // Could be OR
array( 'taxonomy' => 'MyTaxonomy1',
'field' => 'MySlug1',
'terms' => array( 'MyTerm11',
'MyTerm12' ), ),
array( 'taxonomy' => 'MyTaxonomy2',
'field' => 'MySlug2',
'terms' => array( 'MyTerm21',
'MyTerm22',
'MyTerm23' ), ) ), );
$ThisQuery = new WP_Query( $Args );
if ( $ThisQuery->have_posts() ) : while ( $ThisQuery->have_posts() ) : $ThisQuery->the_post();
// Do Stuff
endwhile;
endif;
?>