سؤال

How do I limit the query by two custom meta fields, a start date and an end date? This is what my data looks like:

meta_key   | meta_value |
------------------------|
start_date | 20100131   | //Jan 15, 2010
end_date   | 20100206   | //Feb 6, 2010
------------------------'

$today = date(YYYYMMDD);

The post will show if start_date = $today and it will expires when end_date = $today.

update

Here is the structure on my single.php

First Query I use here your answer

<?php
query_posts( $query_string );
if (have_posts()) : while (have_posts()) : the_post();
    ?><a href="<?php the_permalink() ?>"><?php the_title() ?></a><br /><?php
endwhile; endif;
wp_reset_query();
?>

and Second Query with regular wordpress function but this second query doesnt work properly

<?php
query_posts('showposts=5&meta_key=start_date&meta_compare=>&meta_value='.date("Ymd"));
if (have_posts()) : while (have_posts()) : the_post();
    ?><a href="<?php the_permalink() ?>"><?php the_title() ?></a><br /><?php
endwhile; endif;
wp_reset_query();
?>
هل كانت مفيدة؟

المحلول

Edited again to demonstrate adding and removing filters:

Include these general functions in your functions.php. These are the filters you will invoke for the loops where you want to limit your query by these two meta values:

function date_check_join( $join ) {
    global $wpdb;
    $join .= " JOIN ".$wpdb->postmeta." AS startdate ON 
        (".$wpdb->posts.".ID = startdate.post_id AND
        startdate.meta_key = 'start_date')
        JOIN ".$wpdb->postmeta." AS enddate ON 
        (".$wpdb->posts.".ID = enddate.post_id AND
        enddate.meta_key = 'end_date')";
    return $join;
    }

function date_check_where( $where ) {
    $today = date('Ymd');
    $where .= " AND startdate.meta_value <= $today
    AND enddate.meta_value >= $today";
    return $where;
    }

Now, on the page(s) where you want to include these filters, add them before the loops you want to filter and remove them afterward. For example:

add_filter( 'posts_join', 'date_check_join' );
add_filter( 'posts_where', 'date_check_where' );

query_posts( "yourqueryhere" );
if (have_posts()) : while (have_posts()) : the_post();
// This loop will only includes where today is between start_date and end_date
endwhile; endif;

query_posts( "anotherqueryhere" );
if (have_posts()) : while (have_posts()) : the_post();
// This loop also only includes where today is between start_date and end_date
endwhile; endif;

remove_filter( 'posts_join', 'date_check_join' );
remove_filter( 'posts_where', 'date_check_where' );

query_posts( "thirdqueryhere" );
if (have_posts()) : while (have_posts()) : the_post();
// This loop is not affected by the filters, so you can query for posts 
// where start_date is in the future, or end_date in the past, etc.
endwhile; endif;

You just need to add your conditions to the 'posts_join' and 'posts_where' filters before your search, and remove them afterwards (otherwise these conditions will be applied to everything on your site, including pages, menus, etc.)

If you can simplify this by only comparing against one field, then you can use the meta_compare attribute built into the WP_Query object. You could schedule your posts for the start_date (so they don't show ahead of schedule), and then compare the date against the end_date custom field when you query.

نصائح أخرى

The answer to this question: How to Change Loop to Order Posts by Views (using wp-postviews plugin) shows you how to sort by a custom field.

Take a look at the Codex docs for query_posts(): http://codex.wordpress.org/Template_Tags/query_posts, and look a the custom field sections.

Then, all you need to do is include a test within the loop to skip if ($today < start_date or $today > end_date)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى wordpress.stackexchange
scroll top