I have a loop that is pulling all of the news out, however there is three main stories set by ACF. These are Main, Secondary and Third. This wouldn't be a problem if there was only one post set to each field. However, the client wants to be able to just set a new Main post without having to worry about removing the old ones.
So to make that work I'm trying to get the loop to ignore the first of these three fields, while showing the rest AND the other posts that are set to 'No'.
I'm trying something like this but I just cannot see how else to do it.
$args = array(
// 'offset' => 1,
'posts_per_page' => -1,
'meta_query' => array(
array(
'offset' => 1,
'key' => 'main_story',
'value' => 'Secondary',
'compare' => 'NOT',
)
),
'meta_query' => array(
array(
'offset' => 1,
'key' => 'main_story',
'value' => 'Third',
'compare' => 'NOT',
)
),
'meta_query' => array(
array(
'offset' => 1,
'key' => 'main_story',
'value' => 'Main',
'compare' => 'NOT',
)
),
);
I know offset removes the ability to paginate which is important, but I saw https://codex.wordpress.org/Making_Custom_Queries_using_Offset_and_Pagination and also was told a way to go around this. This part is more important for the time being.
Here's how I finally got around not being able to do the above
<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; ?>
<?php
$excluded_key = "main_story";
$excluded_val = array("Main", "Secondary", "Third");
$exclude_ids = array();
?>
<?php
foreach ($excluded_val as $exclude) {
$args = array(
'posts_per_page' => 1,
'order' => 'DESC',
'meta_query' => array(
array(
'key' => $excluded_key,
'value' => $exclude,
)
)
);
$excluded_id = get_posts($args);
foreach($excluded_id as $to_exclude) {
$exclude_ids[] = $to_exclude->ID;
}
}
?>
<?php
$args = array(
'post__not_in' => $exclude_ids,
'paged' => $paged
);
?>
<?php $the_query = new WP_Query( $args ); ?>
<?php if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
Related
Tried searching and testing for two days now, but don't seem to get this loop working in the way that I want it. Any help would be greatly appreciated.
I want to loop through a custom post type (I know how to do this)
In this loop, I first would like to list a few posts (number can vary) with a custom field value ('yes'), and then sort these posts based on a taxonomy value (length).
Then I would like to list the rest of the posts (these have a custom field value 'no') and sort these posts based on a taxonomy value (year).
These pages use pagination. I tried two different loops but since the first part is an undefined number of posts, this does not work for me. And on top of that it just feels 'cleaner' in one loop if possible.
So far this is what I have:
<?php $args = array(
'post_type' => 'custom-post-type-name',
'posts_per_page' => 24,
'paged' => $paged,
'meta_query' => array(
'first-posts' => array(
'meta_key' => 'highlighted-post',
'meta_value' => 'yes',
),
'other-posts' => array(
'meta_key' => 'highlighted-post',
'meta_value' => 'no'
),
),
'orderby' => array(
'first-posts' => 'ASC',
'other-posts' => 'DESC'
),
); ?>
You have to make two queries, one for the 'yes' posts and another for the 'no'. Also, your query is wrong when calling meta query.
We set the pagination:
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
The 'yes' posts:
<?php $yes_posts = get_posts(array(
'post_type' => 'custom-post-type-name',
'posts_per_page' => 24,
'paged' => $paged,
'meta_query' => array(
array(
'meta_key' => 'highlighted-post',
'meta_value' => 'yes',
),
),
'order' => 'ASC'
)); ?>
The 'no' posts:
<?php $no_posts = get_posts(array(
'post_type' => 'custom-post-type-name',
'posts_per_page' => 24,
'paged' => $paged,
'meta_query' => array(
array(
'meta_key' => 'highlighted-post',
'meta_value' => 'no'
),
),
'orderby' => 'DESC'
)); ?>
We combine the queries to get a list of post ids for the last query:
$allposts = array_merge($yes_posts, $no_posts);
$postids = array();
foreach( $allposts as $item ) {
$postids[] = $item->ID;
}
We create an array of post IDs
$unique = array_unique($postids);
$args = array(
'post__in' => $unique,
'paged' => $paged,
'orderby' => 'post__in'
);
We do the loop:
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) {
$checking = 0;
while ( $the_query->have_posts() ) { $the_query->the_post();
// Handle posts here
}
wp_reset_postdata();
}
Combine every code in a page and it should work.
My code for pagination in woocomerce is the following:
global $paged;
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'product',
'hide_empty' => 1,
'depth' => 1,
'posts_per_page' => 30,
'orderby' => 'name',
'order' => 'ASC',
'update_post_term_cache' => false,
'update_post_meta_cache' => false,
'paged' => $paged
);
$loop = new WP_Query( $args );
echo '<div class="woocomerce-paginador">';
echo paginate_links( array(
'format' => '?paged=%#%',
'current' => max( 1, $loop->get( 'paged' ) ),
'total' => $loop->max_num_pages
) );
echo '</div>';
wp_reset_postdata();
I can not figured why but some pages are blank.
For example page one is blank, but page two has products.
Well, i figured out what was the problem.
I have products with no price, and pagination was trying to show no price products but instead it showed blank pages, because of condition i have in my code to only show priced products.
I solved the problem with a meta query.
'meta_query' => array(
array(
'key' => '_price',
'value' => 0,
'compare' => '>',
'type' => 'NUMERIC'
)
),
I'm working on a wordpress of a soccer club and I want to display events (matches) for the current week.
I have to sort by ACF field called "date_match" and not the date of the post itself but it doesn't work.
Matches are custom post type.
Here is my query
<?php
//define args
$args = array(
'post_type' => 'matchs',
'orderby' => 'meta_value',
'meta_key' => 'date_match',
'order' => 'ASC',
'posts_per_page' => 4,
// Using the date_query to filter posts from last week
'meta_query' => array(
array(
'key' => 'date_match',
'year' => date( 'Y' ),
'week' => date( 'W' )
)
)
);
//query
$the_query = new WP_Query( $args );
//loop
if ($the_query->have_posts()): while ($the_query->have_posts()) : $the_query->the_post();
?>
…
<?php endwhile; ?>
<?php else: ?>
<!-- article -->
<article>
<h6>No match to display.</h6>
</article>
<!-- /article -->
<?php endif; ?>
And here is my configuration in ACF :
You can try something like:
$start = 'define your start date';
$end = 'define your end date';
// update your meta_query to search for posts between start and end
'meta_query' => array(
array(
'key' => 'date_match',
'value' => array($start, $end),
'compare' => 'BETWEEN',
'type' => 'DATE'
)
<?php
//define args
//timestamp used to format the date
$thisMonday = strtotime('this week');
$thisFriday = strtotime('+6 days', $thisMonday);
$thisMonday = date('Ymd', $thisMonday);
$thisFriday = date('Ymd', $thisFriday);
$args = array(
'post_type' => 'matchs',
'orderby' => 'meta_value',
'meta_key' => 'date_match',
'order' => 'ASC',
'posts_per_page' => 4,
// Using the date_query to filter posts from this week
'meta_query' => array(
array(
'key' => 'date_match',
'value' => $thisMonday,
'compare' => '>='
),
array(
'key' => 'date_match',
'value' => $thisFriday,
'compare' => '<='
)
)
);
//query
$the_query = new WP_Query( $args );
//loop
if ($the_query->have_posts()): while ($the_query->have_posts()) : $the_query->the_post();
?>
There is the following code, the problem is that it displays all the goods in a row, regardless of status, but I would like to display only those that are "in stock".
function get_products($categories = array(), $product_type = 'featured_product', $paged = 1, $post_per_page = -1, $orderby = '', $order = '') {
global $woocommerce, $wp_query;
$args = array(
'post_type' => 'product',
'posts_per_page' => $post_per_page,
'post_status' => 'publish',
'paged' => $paged,
'orderby' => $orderby,
'order' => $order
); }
I'm not really sure what you're trying to do with your code, as your function and your args seem to be unrelated... but if you're just trying to get the products, try a custom loop:
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'post_status' => 'publish',
'paged' => $paged,
'tax_query' => array(
array(
'taxonomy' => 'product_visibility',
'field' => 'name',
'terms' => 'featured',
),
),
'meta_query' => array(
array(
'key' => '_stock_status',
'value' => 'instock',
'compare' => '=',
),
),
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) : $query->the_post();
// Do stuff.
endwhile;
endif;
wp_reset_postdata();
Note that I have not tested this and you clearly have something unique going on with how you're trying to display the posts, so you may need to make a few adjustments.
I am using two loop query:
<?php
// show all coupons marked Top Coupon
query_posts(array(
'post_type' => APP_POST_TYPE,
'post_status' => 'publish',
'meta_key' => 'clpr_topcoupon',
'meta_value'=> 1,
APP_TAX_STORE => $term->slug,
'ignore_sticky_posts' => 1,
'posts_per_page' => 1
));
?>
<?php get_template_part( 'loop3', 'coupon' ); ?>
<?php
query_posts( array(
'post_type' => APP_POST_TYPE,
'post_status' => 'publish',
APP_TAX_STORE => $term->slug,
'ignore_sticky_posts' => 1,
'posts_per_page' => -1,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'clpr_excoupon',
'compare' => 'NOT EXISTS'
),
array(
'key' => 'clpr_excoupon',
'compare' => '!=',
'value' => '1'
),
),
) );
?>
<?php get_template_part( 'loop1', 'coupon' ); ?>
Now I don't want to show the first post from the first loop in the second loop. I tried get_the_ID(); however if this one is not having the 'meta_key' => 'clpr_topcoupon' one post is missing. How do I get the get_the_ID(); from first post but only if it has the 'meta_key' => 'clpr_topcoupon'?
Wordpress docs suggest that you should avoid using query_posts whenever possible stating:
Note: This function will completely override the main query and isn’t intended for use by plugins or themes. Its overly-simplistic approach to modifying the main query can be problematic and should be avoided wherever possible.
Instead we can use WP_Query . We'll use the first loop to store the post id and check it during the second loop. Maybe something like this:
<?php
//set parameters for First query
$args = array('post_type' => APP_POST_TYPE,
'post_status' => 'publish',
'meta_key' => 'clpr_topcoupon',
'meta_value'=> 1,
APP_TAX_STORE => $term->slug,
'ignore_sticky_posts' => 1,
'posts_per_page' => 1 );
$first_query = new WP_Query($args); // create query
$post_id = 0;
//initialize loop for custom query like this
if ($first_query->have_posts() ) {
while ($first_query->have_posts() ) {
$first_query->the_post();
$post_id = $post->ID; //store post ID outside of loop
get_template_part( 'loop3', 'coupon' );
}
}
wp_reset_postdata();
//setup second query
$args = array( //excludes post from query by ID See Bill erikson for complete list of WP_Query() arguments
'post__not_in' => array($post_id),
'post_type' => APP_POST_TYPE,
'post_status' => 'publish',
APP_TAX_STORE => $term->slug,
'ignore_sticky_posts' => 1,
'posts_per_page' => -1,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'clpr_excoupon',
'compare' => 'NOT EXISTS'
),
array(
'key' => 'clpr_excoupon',
'compare' => '!=',
'value' => '1'
)
)
);
$second_query = new WP_Query($args);
if ($second_query->have_posts() ) {
while ($second_query->have_posts() {
$second_query->the_post();
get_template_part( 'loop1', 'coupon' );
}
}
wp_reset_postdata();
Hopefully, this code is able to assist you. As you can see, WP_Query accepts an argument 'post__not_in' that takes an array of page id's and excludes them from the query. We retrieved the id from the first query and referenced it in the argument of the second query. I also included wp_reset_postdata which is worth taking a look at if you're running multiple queries.
Good luck with your project!