メタ値または日付で注文しますか?


10

カスタムフィールドが呼び出されましたstartDateが、それはいくつかのイベントでのみです。post_date投稿リストの生成に使用できる投稿に設定されていないのでしょうか。

// if meta_key _postmeta.startDate isn't set get the rest by posts.post_date

query_posts(
    array(
        array(
            'posts_per_page' => 10,
            'meta_key' => 'startDate',
            'meta_value' => date('Y-m-d'),
            'meta_compare' => '<',
            'orderby' => 'meta_value',
            'order' => 'ASC'
        ), 
        array(
            'meta_key' => 'post_date',
            'meta_value' => date('Y-m-d'),
            'meta_compare' => '<'
        )
    )
);

post_dateはカスタムフィールドですか?
Bainternet、2011年

間違っているかもしれませんが、デフォルトのワードプレス公開フィールドを想定していますか?どちらの方法でも、デフォルトの日付を使用したい...
v3nt


クエリの引数を修正しました。これにより、説明している内容がまったく歪んでいないことを願っています。必要に応じて、元に戻してください。
t31os 2011年

cheers t31os-わかりやすくするためにもう一度編集しました。startDateを使用してNOWより古いコンテンツを選択する必要があります。startDateが設定されていない場合は、デフォルトの投稿の日付post_dateを使用します。
v3nt 2011年

回答:


11

SQLで説明できる場合は、クエリを実行できます。デフォルトクエリを変更する場所は3つあります。

SELECT wp_posts.*
FROM wp_posts 
INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)
WHERE 1=1
    AND wp_posts.post_type = 'post'
    AND (wp_posts.post_status = 'publish')
    AND wp_postmeta.meta_key = 'startDate'
    AND CAST(wp_postmeta.meta_value AS CHAR) < '2011-03-23'
GROUP BY wp_posts.ID
ORDER BY wp_postmeta.meta_value DESC
LIMIT 0, 10
  • 結合は左結合でなければなりません
  • where句
  • オーダー

結合とwhere句は_get_meta_sql()関数を介し追加されます。出力はフィルターされているので、それにフックできます。

add_filter( 'get_meta_sql', 'wpse12814_get_meta_sql' );
function wpse12814_get_meta_sql( $meta_sql )
{
    // Move the `meta_key` comparison in the join so it can handle posts without this meta_key
    $meta_sql['join'] = " LEFT JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = 'startDate') ";
    $meta_sql['where'] = " AND (wp_postmeta.meta_value IS NULL OR wp_postmeta.meta_value < '" . date('Y-m-d') . "')";
    return $meta_sql;
}

注文句は次のようにフィルタリングされますposts_orderby

add_filter( 'posts_orderby', 'wpse12814_posts_orderby' );
function wpse12814_posts_orderby( $orderby )
{
    $orderby = 'COALESCE(wp_postmeta.meta_value, wp_posts.post_date) ASC';
    return $orderby;
}

これにより、次のSQLクエリが得られます。

SELECT wp_posts.*
FROM wp_posts
LEFT JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = 'startDate')
WHERE 1=1
    AND wp_posts.post_type = 'post'
    AND (wp_posts.post_status = 'publish')
    AND (wp_postmeta.meta_value IS NULL OR wp_postmeta.meta_value < '2011-03-23')
GROUP BY wp_posts.ID
ORDER BY COALESCE(wp_postmeta.meta_value, wp_posts.post_date) ASC
LIMIT 0, 10

クエリを実行した後は、フィルターのフックを解除することを忘れないでください。そうしないと、他のクエリも台無しになります。また、可能であれば、自分自身を呼び出すのではなくquery_posts()、ページの設定中にWordPressによって実行されるメインの投稿クエリを変更します。


2
非常にエレガントなソリューションです。COALESCEをそのように使用することは考えていませんでした。デフォルトの「wp_」接頭辞を想定せず、代わりに{$ wpdb-> prefix}を使用することをお勧めします...
goldenapples

@goldenapples:はい、あなたはそれを一般化することができますが、それはこのクエリに対してすでに非常に具体的であり(メタパーツで他のクエリを混乱させることになる)、これは必要ないと考えました。
Jan Fabry

ありがとう、Jan-それは目を見張るものです!まだワードプレスに慣れていて、これが私のページのどこに呼び出されているのか疑問に思っていますか?そして、私はそれをどのように「フック解除」しますか?ie // $ theQuery ... then <?php if(have_posts()):while(have_posts()):the_post(); ?>?
v3nt 2011年

@daniel:関数をテーマのfunctions.phpファイルに配置できます。次に、クエリを実行する直前に、2 add_filter()行を配置します。クエリの後で、remove_filter( 'get_meta_sql', 'wpse12814_get_meta_sql' ); remove_filter( 'posts_orderby', 'wpse12814_posts_orderby' );それらを再度削除するように記述します。
Jan Fabry

ああ-それは今すべて意味があり、また働いています!1月ザッツつもりが有用である多くの感謝...
v3nt

0

以下に沿って何かを試してください:

$postedtime = get_post_meta($post->ID, 'startDate');

if($postedtime != null){
$orderby = $postedtime;

}else{
$orderby = 'date';
}

アレックスに感謝しますが、これがループに関与する方法がわかりませんか?
v3nt 2011年

どー!query_posts(array( 'orderby' => $ orderby))の場合
Alex Older

0

クエリ投稿呼び出しは、2つではなく1つのクエリのみを作成します。したがって、2つの別々のクエリを作成して、結果を連結することはできません。

ここでは、投稿のセットを選択して表示しています。そのセットが一度に選択されます。2つの別個の投稿セットを取得してからそれらをマージする場合は、get_postsまたは同様の方法で自分で行う必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.