Meta değere veya tarihe göre sıralama?


10

Özel bir alan var startDateama sadece birkaç olay. Yazı post_datelistesini oluşturmak için kullanabileceğim bir yazı için ayarlanmadığını merak ediyordum ?

// 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 özel bir alan mı?
Bainternet

i yanlış olsa da onun varsayılan wordpress yayınlanan alanı varsayıyorum? Her iki şekilde de varsayılan tarihi kullanmak istiyorum ...
v3nt

Tamam, bu bir meta alan değil onun
yazı

Sorgu argümanlarınızı düzelttik, gösterdiğiniz şeyi hiç çarpmadığını umuyoruz, lütfen gerekirse geri dönmekten çekinmeyin.
t31os

şerefe t31os - daha net hale getirmek için tekrar düzenledi. StartDate kullanarak ŞİMDİ eski olan içeriği seçmek için ona ihtiyacınız var ve startDate ayarlanmadıysa varsayılan yazıların post_date tarihini kullanın.
v3nt

Yanıtlar:


11

SQL'de açıklayabilirseniz, sorgulayabilirsiniz! Varsayılan sorguyu değiştirmek istediğimiz üç yer vardır:

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
  • Birleştirme soldan birleştirme olmalıdır
  • Nerede fıkra
  • Emir

Katılıp burada-maddesi ile eklenir fonksiyonu . Çıktı filtrelenir, böylece içine bağlanabiliriz:_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;
}

Sipariş cümlesi şununla filtrelenir 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;
}

Bu bize aşağıdaki SQL sorgusunu verir:

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

Sorgunuzu yaptıktan sonra filtreleri açmayı unutmayın, aksi takdirde diğer sorguları da karıştırırsınız. Ve mümkünse çağrı olmamalıdır query_posts()kendini ancak sayfasını kurarken WordPress tarafından yapılır ana sonrası sorguyu değiştirin.


2
Çok zarif bir çözüm, COALESCE'i böyle kullanmayı düşünmezdim. Sadece varsayılan 'wp_' önekini almamayı ve bunun yerine {$ wpdb-> prefix} 'i kullanmamanızı tavsiye ederim ...
goldenapples

@goldenapples: Evet, genelleştirebilirsiniz, ancak bu sorgu için zaten çok özel (bu meta parçası ile diğer sorguları berbat edecek), bunun gerekli olmadığını düşündüm.
Jan Fabry

Teşekkürler Jan - bu bir göz açıcı! Hala wordpress ile uğraşmak ve bunun sayfamda nerede aradığını merak mı ediyorsunuz? Ve bunu nasıl 'açarım'? yani // $ theQuery ... sonra <? php if (have_posts ()): while (have_posts ()): the_post (); ?>?
v3nt

@daniel: İşlevleri temanızın functions.phpdosyasına yerleştirebilirsiniz. Ardından sorguyu yürütmeden hemen önce iki add_filter()satırı yerleştirirsiniz. Sorgudan sonra remove_filter( 'get_meta_sql', 'wpse12814_get_meta_sql' ); remove_filter( 'posts_orderby', 'wpse12814_posts_orderby' );tekrar kaldırmak için yazıyorsunuz .
Jan Fabry

ah - şimdi hepsi mantıklı ve çalışıyor! Çok teşekkürler Jan. Bu yararlı olacak ...
v3nt

0

Aşağıdaki konularda bir şeyler deneyin:

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

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

}else{
$orderby = 'date';
}

teşekkür alex ama bu döngü dahil nasıl emin değilim?
v3nt

doh! query_posts (array ('orderby' => $ orderby))
Alex

0

Bir sorgu mesajı çağrısı iki değil, yalnızca bir sorgu yapar. Yani hayır, iki ayrı sorgu yapmasını ve ardından sonuçları birleştirmesini sağlayamazsınız.

Unutmayın, burada bazı yayınları seçip görüntülersiniz. Bu set bir kerede seçilir. İki ayrı gönderi seti almak ve sonra birleştirmek istiyorsanız, bu get_posts veya benzeri bir şeyle kendinizi yapmanız gereken bir şeydir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.