Ask your WordPress questions! Pay money and get answers fast! (more info)

1. New Query: All posts showing up on taxonomy pages 2. Sorting WordPress

  • SOLVED

I have custom post types ("coupon") and an archive for these custom post types ("coupons").

Now i´m using this code to order posts by date via custom field "unixendet" in my custom template archive-custom.php:

<?php

$args = array(
'post_type' => 'coupon',
'pagination' => true,
'posts_per_page' => '20',
'posts_per_archive_page' => '20',
'ignore_sticky_posts' => false,
'paged' => $paged,
'meta_key' => 'unixendet',
'orderby' => 'meta_value_num',
'order' => 'DESC',
);

// get results
$the_query = new WP_Query( $args );

// The Loop
?>
<?php if( $the_query->have_posts() ): ?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>


For the archives page (coupons) it is working, but now all the posts of custom post type "coupon" are showing up on taxonomy pages ("onlinestore").

How can i get it work like before, where only these posts were showing up on taxonomy pages ("onlinestore"), which were related to them? Not all! Is there any value, which i´ve missed in my custom query?
<strong>
My second question:</strong>

How can i sort the coupons by custom field "unixendet", but to show up first these coupons, that are ending soon, instead of simply sort it by highest stored unix value. The expired posts should be appearing like before at the end of the list.



Answers (1)

2015-03-03

Romel Apuya answers:

hi,

your archive-custom.php should be archiev-coupons.php
thats the template for archive for custom post type,
to order the expired coupons use order by date,


emti comments:

OK i solved my first question by my own:

Seperated with if is_tax and used this:

$qobj = get_queried_object();
// var_dump($qobj); // debugging only

$args = array(
'post_type' => 'gutschein',
'pagination' => true,
'posts_per_page' => '20',
'posts_per_archive_page' => '20',
'ignore_sticky_posts' => false,
'paged' => $paged,
'meta_key' => 'unixendet',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'tax_query' => array(
array(
'taxonomy' => $qobj->taxonomy,
'field' => 'id',
'terms' => $qobj->term_id,
// using a slug is also possible
// 'field' => 'slug',
// 'terms' => $qobj->name
)
)
);


<strong>Can anybody tell me how to solve my second question?</strong>

I´ve already sorted my posts by unix data from custom field "unixendet":

- Posts with bigger difference [ending date <-> date today] are already on top of query.

But i want:

- Posts with smaller difference [ending date <-> date today] should be on top of query.
- AND: Posts which are expired should be at the bottom of all, of course.

The ending date means my custom field value "unixendet".



Romel Apuya comments:

change orderby to meta_value


emti comments:

Tried this, but it changed nothing. Still 31.06.2015 over 31.04.2015.

My custom fields have Unix Values like: 1428271200


Romel Apuya comments:

change desc to asc


emti comments:

If i change desc to asc, the oldest coupons, which are already expired, are showing up on the top.

Another explanation try:

I need:

New Coupon ending 07.03.2015
New Coupon ending 08.03.2015
New Coupon ending 09.03.2015
New Coupon ending 10.03.2015
--- TODAY
Old Coupon ended 02.03.15
Old Coupon ended 01.03.15
...

Maybe something like that:

date_default_timezone_set('Europe/Berlin'); setlocale(LC_TIME, "de_DE", "german");
$today = time();

....

'meta_query' => array(
'key' => 'endet',
'compare' => '>=',
'value' => $today,


Or do i have to make two queries? One with the posts, which have higher value compared to today and another query with the posts with lower value compared to today?

But how to exclude older ones from the new post query / newer ones from the old posts query.





Romel Apuya comments:

$qobj = get_queried_object();
date_default_timezone_set('Europe/Berlin');
setlocale(LC_TIME, "de_DE", "german");
$time = current_time( 'timestamp' ); // Get current unix timestamp
$args = array(
'post_type' => 'gutschein',
'pagination' => true,
'posts_per_page' => '20',
'posts_per_archive_page' => '20',
'ignore_sticky_posts' => false,
'paged' => $paged,
'meta_key' => 'unixendet',
'meta_compare'=> '>='
'meta_value' => $time, // Use the current time from above
'meta_compare' => '>=', // Compare today's datetime with our event datetime
'orderby' => 'meta_value_num',
'order' => ASC,
'tax_query' => array(
array(
'taxonomy' => $qobj->taxonomy,
'field' => 'id',
'terms' => $qobj->term_id
)
)
);


Romel Apuya comments:

this rather. i forgot the , after the meta_compare
$qobj = get_queried_object();
$time = current_time( 'timestamp' ); // Get current unix timestamp
$args = array(
'post_type' => 'gutschein',
'pagination' => true,
'posts_per_page' => '20',
'posts_per_archive_page' => '20',
'ignore_sticky_posts' => false,
'paged' => $paged,
'meta_key' => 'unixendet',
'meta_compare'=> '>=',
'meta_value' => $time, // Use the current time from above
'meta_compare' => '>=', // Compare today's datetime with our event datetime
'orderby' => 'meta_value_num',
'order' => ASC,
'tax_query' => array(
array(
'taxonomy' => $qobj->taxonomy,
'field' => 'id',
'terms' => $qobj->term_id
)
)
);


Romel Apuya comments:

$qobj = get_queried_object();
date_default_timezone_set('Europe/Berlin');
setlocale(LC_TIME, "de_DE", "german");
$time = current_time( 'timestamp' ); // Get current unix timestamp
$args = array(
'post_type' => 'gutschein',
'pagination' => true,
'posts_per_page' => '20',
'posts_per_archive_page' => '20',
'ignore_sticky_posts' => false,
'paged' => $paged,
'meta_key' => 'unixendet',
'meta_compare'=> '>=',
'meta_value' => $time, // Use the current time from above
'meta_compare' => '>=', // Compare today's datetime with our event datetime
'orderby' => 'meta_value_num',
'order' => ASC,
'tax_query' => array(
array(
'taxonomy' => $qobj->taxonomy,
'field' => 'id',
'terms' => $qobj->term_id
)
)
);


emti comments:

Ok i´ve used this for my coupons archive page:


date_default_timezone_set('Europe/Berlin'); setlocale(LC_TIME, "de_DE", "german");
$time = current_time( 'timestamp' ); // Get current unix timestamp

$args = array(
'post_type' => 'gutschein',
'pagination' => true,
'posts_per_page' => '20',
'posts_per_archive_page' => '20',
'ignore_sticky_posts' => false,
'paged' => $paged,
'meta_key' => 'unixendet',
'meta_value' => $time, // Use the current time from above
'meta_compare' => '>=', // Compare today's datetime with our event datetime
'orderby' => 'meta_value_num',
'order' => ASC,
);


- Little Bug: I have had 3 result pages before with new and old coupons together. But now i have 3 pages, too. But 2 of them with blank results.
- How can i add the older coupons, when i´m using your solution? They aren´t showing up with that query. Can i combine two queries in one query (someting like AND)?


Romel Apuya comments:

try adding post_status published from the query.


Romel Apuya comments:

yes you can always join queries with and


emti comments:

Ok now i have combined the queries:


$args = array(
'post_type' => 'gutschein',
'pagination' => true,
'posts_per_page' => '20',
'posts_per_archive_page' => '20',
'ignore_sticky_posts' => false,
'post_status' => 'published',
'paged' => $paged,
'meta_key' => 'unixendet',
'meta_value' => $time, // Use the current time from above
'meta_compare' => '>=', // Compare today's datetime with our event datetime
'orderby' => 'meta_value_num',
'order' => ASC,
);

// get results
$the_query = new WP_Query( $args );

$args2 = array(
'post_type' => 'gutschein',
'pagination' => true,
'posts_per_page' => '20',
'posts_per_archive_page' => '20',
'ignore_sticky_posts' => false,
'post_status' => 'published',
'paged' => $paged,
'meta_key' => 'unixendet',
'meta_value' => $time, // Use the current time from above
'meta_compare' => '<=', // Compare today's datetime with our event datetime
'orderby' => 'meta_value_num',
'order' => DESC,
);

$new_query = new WP_Query( $args2 );

$result = new WP_Query();
$result->posts = array_merge( $the_query->posts, $new_query->posts );
$result->post_count = count( $result->posts );

// The Loop
?>
<?php if( $result->have_posts() ): ?>
<?php while ( $result->have_posts() ) : $result->the_post(); ?>


I have 48 coupons: 11 from args1 AND 37 from args2

Result:
First page: 11 from args1 and 20 from args2
Second page: 17 from args2
Third page: blank result

Is there something wrong with counting or what is the reason for this behaviour?


emti comments:

Could it be, that it takes the value from reding section in wordpress settings? There i have 20 as value for max. blogposts.


Romel Apuya comments:

hi,

I dont think you really need two query on this.


try this

<?php
date_default_timezone_set('Europe/Berlin');
setlocale(LC_TIME, "de_DE", "german");
$time = current_time( 'timestamp' ); // Get current unix timestamp
$args = array (
'post_type' => 'gutschein',
'post_status' => 'publish',
'orderby' => 'meta_value',
'meta_key' => 'unixendet',
'meta_value' => $time,
'meta_compare' => '>=',
'order' => 'ASC',
'posts_per_page' => 20,
'ignore_sticky_posts' => false,
);

$query = new WP_Query( $args );

if ( $query->have_posts() ) :

while ( $query->have_posts() ) : $query->the_post(); // Start loop

// Your custom loop code here

wp_reset_postdata();

endif;
?>


if the above wont work.. add wp_reset_postdata() before

$args2 = array(.... of your code from above....


emti comments:

'post_status' => 'publish'

It doesn´t help, because all coupons, even the older coupons, are still "published". The only difference is the expired factor, which is based on today-customfield relations.

... So i think i have to combine.


Romel Apuya comments:

have you tried the above code??.


emti comments:

If i set

'posts_per_page' => '10',
'posts_per_archive_page' => '10',


this results:
first page: 10 from args1 and 10 from args2
second page: 1 from args1 and 10 from args2
third page: 0 from args1 and 10 from args2

- So on second page there is 1 valid coupon, so it would make no sense to sort like this.
- It seems that 7 coupons are missing from args2 (page number 4 doesn´t exist.) Only 30 from 37 posts.

the second bug is very strange.



emti comments:

Yes i tried the code. The expired coupons which are the opposite from 'meta_compare' => '>=', are missing! If i change it to '<=' the posts (valid coupons) are missing.


Romel Apuya comments:

<code>$args = array(
'post_type' => 'gutschein',
'pagination' => true,
'posts_per_page' => '20',
'posts_per_archive_page' => '20',
'ignore_sticky_posts' => false,
'post_status' => 'publish',
'paged' => $paged,
'meta_key' => 'unixendet',
'meta_value' => $time, // Use the current time from above
'meta_compare' => '>=', // Compare today's datetime with our event datetime
'orderby' => 'meta_value_num',
'order' => ASC,
);
// get results
$the_query = new WP_Query( $args );
wp_reset_postdata();

$args2 = array(
'post_type' => 'gutschein',
'pagination' => true,
'posts_per_page' => '20',
'posts_per_archive_page' => '20',
'ignore_sticky_posts' => false,
'post_status' => 'publish',
'paged' => $paged,
'meta_key' => 'unixendet',
'meta_value' => $time, // Use the current time from above
'meta_compare' => '<=', // Compare today's datetime with our event datetime
'orderby' => 'meta_value_num',
'order' => DESC,
);
$new_query = new WP_Query( $args2 );
$result = new WP_Query();
$result->posts = array_merge( $the_query->posts, $new_query->posts );
$result->post_count = count( $result->posts );
// The Loop
?>
<?php if( $result->have_posts() ): ?>
<?php while ( $result->have_posts() ) : $result->the_post();
wp_reset_postdata();
</code>

can you send me ftp details?
sent you PM.


emti comments:

No same problem like before:

If i use:

'posts_per_page' => '10',

Problem 1: On the second page there is 1 valid coupon, so it would make no sense to sort like this. I want all valid ones stay above the expired ones.
Problem 2: It seems that 7 coupons are missing from args2 (page number 4 doesn´t exist.) So only 30 from 37 expired posts are showing up.

I can´t give ftp access. And i´m not using skype at this moment.
greets


emti comments:

It should looks like this:

New Coupon ending TODAY ---
New Coupon ending 05.03.2015
New Coupon ending 06.03.2015
New Coupon ending 07.03.2015
---
Old Coupon expired 03.03.15
Old Coupon expired 02.03.15
Old Coupon expired 01.03.15


emti comments:

I tried this but it breaks site layout. But something like this should be the solution, i think:


date_default_timezone_set('Europe/Berlin'); setlocale(LC_TIME, "de_DE", "german");
$time = current_time( 'timestamp' ); // Get current unix timestamp

//-----------------
// Query part #1:
//-----------------
$args1 = array(
'post_type' => 'gutschein',
'orderby' => 'meta_value_num',
'meta_key' => 'unixendet',
'ignore_sticky_posts' => 1,
'order' => DESC,
'date_query' => array(
array('after' => $time,
),
'inclusive' => true,
)
);

//-----------------
// Query part #2:
//-----------------
$args2 = array(
'post_type' => 'gutschein',
'orderby' => 'meta_value_num',
'meta_key' => 'unixendet',
'ignore_sticky_posts' => 1,
'order' => ASC,
'date_query' => array(
array(
'before' => $time,
),
'inclusive' => true,
)
);

//---------------------------
// Combined queries #1 + #2:
//---------------------------
$args = array(
'posts_per_page' => 20,
'paged' => ( $paged = get_query_var( 'paged' ) ) ? $paged : 1 ,
'sublimit' => 1000,
'args' => array( $args1, $args2 ),
);
$results = new WP_Combine_Queries( $args );
?>
<?php if( $results->have_posts() ): ?>
<?php while ( $results->have_posts() ) : $results->the_post(); ?>



Romel Apuya comments:

ok seems you dont need a combine query.,
two diff query is what you need,.. timestamp greater than the current date are valid coupons, timestamp less than the current are expired ones


emti comments:

Yes, but how can i do that with pagination?

My example code from above is from here: [[LINK href="http://wordpress.stackexchange.com/questions/159228/combining-two-wordpress-queries-with-pagination-is-not-working"]]http://wordpress.stackexchange.com/questions/159228/combining-two-wordpress-queries-with-pagination-is-not-working[[/LINK]]

Seems to be conflicts with:

$results = new WP_Combine_Queries( $args );

experimental?


Romel Apuya comments:

<?php
date_default_timezone_set('Europe/Berlin');
setlocale(LC_TIME, "de_DE", "german");
$time = current_time( 'timestamp' ); // Get current unix timestamp
$args = array(
'post_type' => 'gutschein',
'pagination' => true,
'posts_per_page' => '20',
'posts_per_archive_page' => '20',
'ignore_sticky_posts' => false,
'post_status' => 'publish',
'paged' => $paged,
'meta_key' => 'unixendet',
'meta_value' => $time,
'meta_compare' => '>=',
'orderby' => 'meta_value_num',
'order' => DESC,
);

$the_query = new WP_Query( $args );
if( $the_query->have_posts() ):
while ( $the_query->have_posts() ) :
$the_query->the_post();
wp_reset_postdata();
endif;
$args2 = array(
'post_type' => 'gutschein',
'pagination' => true,
'posts_per_page' => '20',
'posts_per_archive_page' => '20',
'ignore_sticky_posts' => false,
'post_status' => 'publish',
'paged' => $paged,
'meta_key' => 'unixendet',
'meta_value' => $time,
'meta_compare' => '<=',
'orderby' => 'meta_value_num',
'order' => DESC,
);
$new_query = new WP_Query( $args2 );
$result = new WP_Query();
// The Loop
if( $result->have_posts() ):
while ( $result->have_posts() ) :
$result->the_post();
wp_reset_postdata();
endif;


Romel Apuya comments:

based from the link you've given


<?php
date_default_timezone_set('Europe/Berlin');
setlocale(LC_TIME, "de_DE", "german");
$time = current_time( 'timestamp' ); // Get current unix timestamp

$args1 = array(
'ignore_sticky_posts' => 1,
'post_status' => 'publish',
'meta_key' => 'unixendet',
'meta_value' => $time,
'meta_compare' => '>=',
'orderby' => 'meta_value_num',
'order' => DESC,
);

$args2 = array(
'ignore_sticky_posts' => 1,
'post_status' => 'publish',
'meta_key' => 'unixendet',
'meta_value' => $time,
'meta_compare' => '<=',
'orderby' => 'meta_value_num',
'order' => ASC,
);


$args = array(
'posts_per_page' => 20,
'paged' => ( $paged = get_query_var( 'paged' ) ) ? $paged : 1 ,
'sublimit' => 1000,
'args' => array( $args1, $args2 ),
);
$results = new WP_Combine_Queries( $args );
?>


Romel Apuya comments:

<?php
date_default_timezone_set('Europe/Berlin');
setlocale(LC_TIME, "de_DE", "german");
$time = current_time( 'timestamp' ); // Get current unix timestamp

$args1 = array(
'ignore_sticky_posts' => 1,
'post_status' => 'publish',
'meta_key' => 'unixendet',
'meta_value' => $time,
'meta_compare' => '>=',
'orderby' => 'meta_value_num',
'order' => DESC,
);

$args2 = array(
'ignore_sticky_posts' => 1,
'post_status' => 'publish',
'meta_key' => 'unixendet',
'meta_value' => $time,
'meta_compare' => '<=',
'orderby' => 'meta_value_num',
'order' => ASC,
);


$args = array(
'posts_per_page' => 20,
'paged' => ( $paged = get_query_var( 'paged' ) ) ? $paged : 1 ,
'sublimit' => 1000,
'args' => array( $args1, $args2 ),
);
$results = new WP_Combine_Queries( $args );
?>


emti comments:

Ok tested, like i mentioned before, if i set it to smaller value for post_per_page like 10, a valid post (the eleventh one) is on page 2. It´s logical, if you set post per page, the valid posts only show 10 of them and the expired ones even show 10 on one page.

So it continous with eleventh valid post on page 2, and so on...

In this way the eleventh valid post comes after expired posts and that´s not how it should be. So a combined third query should be the solution, i think!!


Romel Apuya comments:

on which query does this happen?? on the two separate or the combined?


emti comments:

Tested both.

Second code breaks layout. Seems to be a problem with

$results = new WP_Combine_Queries( $args );

If i change it to
$results = new WP_Query( $args );
the layout works again, but the query is default and shows all post, even custom post type "post".


Romel Apuya comments:

now im confused..

with one query ordering via timestamp descending and paged so it should order the post from the valid to expired ones..
logically expired ones should be on the end page..


Romel Apuya comments:

If i change it to

$results = new WP_Query( $args );


the layout works again, but the query is default and shows all post, even custom post type "post".


add post_type='gutschein' n both...so it fetches only from the post type.


Romel Apuya comments:

$args1 = array(
'ignore_sticky_posts' => 1,
'post_type' => 'gutschein',
'post_status' => 'publish',
'meta_key' => 'unixendet',
'meta_value' => $time,
'meta_compare' => '>=',
'orderby' => 'meta_value_num',
'order' => DESC,
);

$args2 = array(
'ignore_sticky_posts' => 1,
'post_type' => 'gutschein',
'post_status' => 'publish',
'meta_key' => 'unixendet',
'meta_value' => $time,
'meta_compare' => '<=',
'orderby' => 'meta_value_num',
'order' => ASC,
);


emti comments:

Tested this, too. It changes nothing. The queries seem to be without values if i change it to
$results = new WP_Query( $args );


emti comments:

That´s the solution:

/**
* Modify the order by part:
*/

function emti_orderby( $orderby )
{
global $wpdb;
$time = strtotime( 'today Europe/Berlin' );
// Get current unix timestamp

return "
CASE
WHEN {$wpdb->postmeta}.meta_value >= {$time} THEN -{$wpdb->postmeta}.meta_value+0
WHEN {$wpdb->postmeta}.meta_value < {$time} THEN {$wpdb->postmeta}.meta_value+0 - 9999999999
END
DESC
";
}
?>


emti comments:

And this of course:

<?php

$args = array(
'post_type' => 'gutschein',
'pagination' => true,
'posts_per_page' => '20',
'posts_per_archive_page' => '20',
'ignore_sticky_posts' => false,
'post_status' => 'publish',
'paged' => $paged,
'meta_key' => 'unixendet',
);

add_filter( 'posts_orderby', 'emti_orderby' );
$q = new WP_Query( $args );
remove_filter( 'posts_orderby', 'emti_orderby' );

// The Loop
?>
<?php if( $q->have_posts() ): ?>
<?php while ( $q->have_posts() ) : $q->the_post(); ?>