Dipesan berdasarkan nilai atau tanggal meta?

10

Mendapat bidang khusus yang dipanggil startDatetetapi hanya pada beberapa acara. Saya bertanya-tanya apakah tidak diatur untuk posting yang bisa saya gunakan post_dateuntuk menghasilkan daftar posting?

// 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' => '<'
        )
    )
);
v3nt
sumber
apakah post_date merupakan bidang khusus?
Bainternet
saya anggap bidang default wordpress yang diterbitkan meskipun mungkin salah? Either way id ingin menggunakan tanggal default ...
v3nt
ok jadi ini bukan meta field-nya di tabel postingan
Bainternet
Memperbaiki argumen kueri Anda, harapan yang sama sekali tidak condong pada apa yang Anda ilustrasikan, silakan kembali jika perlu.
t31os
cheers t31os - diedit lagi untuk membuatnya lebih jelas. Perlu untuk memilih konten yang lebih tua dari SEKARANG menggunakan startDate, dan jika startDate belum disetel gunakan tanggal postingan default post_date.
v3nt

Jawaban:

11

Jika Anda dapat menjelaskannya dalam SQL, Anda dapat menanyakannya! Ada tiga tempat di mana kami ingin mengubah kueri default:

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
  • Bergabung harus bergabung kiri
  • Di mana klausa
  • Pesanan

Bergabung dan di mana-klausul yang ditambahkan melalui itu _get_meta_sql()fungsi . Outputnya difilter, jadi kita bisa mengaitkannya:

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;
}

Klausa pesanan disaring melalui 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;
}

Ini memberi kami pertanyaan SQL berikut:

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

Ingatlah untuk melepaskan filter setelah Anda melakukan kueri, jika tidak, Anda juga akan mengacaukan pertanyaan lain. Dan jika mungkin Anda tidak harus menelepon query_posts()diri sendiri , tetapi memodifikasi permintaan posting utama yang dilakukan oleh WordPress saat mengatur halaman.

Jan Fabry
sumber
2
Solusi yang sangat elegan, saya tidak akan berpikir untuk menggunakan COALESCE seperti itu. Saya hanya akan menyarankan untuk tidak mengasumsikan awalan 'wp_' default dan menggunakan awalan {$ wpdb-> sebagai gantinya ...
goldenapples
@goldenapples: Ya, Anda bisa menyamaratakannya, tetapi sudah sangat spesifik untuk permintaan ini (ini akan mengacaukan pertanyaan lain dengan bagian meta), sehingga saya pikir ini tidak perlu.
Jan Fabry
Terima kasih Jan - itu adalah pembuka mata! Masih bisa memahami wordpress dan bertanya-tanya di mana ini disebut pada halaman saya? Dan bagaimana saya akan 'melepasnya'? yaitu // $ theQuery ... lalu <? php if (have_posts ()): while (have_posts ()): the_post (); ?>
v3nt
@daniel: Anda dapat menempatkan fungsi dalam functions.phpfile tema Anda . Kemudian tepat sebelum Anda menjalankan kueri Anda menempatkan dua add_filter()baris. Setelah permintaan Anda menulis remove_filter( 'get_meta_sql', 'wpse12814_get_meta_sql' ); remove_filter( 'posts_orderby', 'wpse12814_posts_orderby' );untuk menghapusnya lagi.
Jan Fabry
ah - itu semua masuk akal sekarang dan bekerja juga! Banyak terima kasih Jan. Thats akan berguna ...
v3nt
0

coba sesuatu di sepanjang baris:

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

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

}else{
$orderby = 'date';
}
Alex Lebih Tua
sumber
alex terima kasih tetapi tidak yakin bagaimana ini terlibat loop?
v3nt
lakukan! ketika Anda query_posts (array ('orderby' => $ orderby))
Alex Older
0

Panggilan posting permintaan membuat hanya satu permintaan, bukan dua. Jadi tidak, Anda tidak dapat membuatnya membuat dua pertanyaan terpisah dan kemudian menggabungkan hasilnya.

Ingat, Anda memilih beberapa posting di sini, lalu menampilkannya. Set itu dipilih sekaligus. Jika Anda ingin mendapatkan dua set posting yang terpisah dan kemudian menggabungkannya, itu adalah sesuatu yang harus Anda lakukan sendiri dengan get_posts atau yang serupa.

Otto
sumber