Sắp xếp theo giá trị meta hoặc ngày?


10

Có một trường tùy chỉnh được gọi startDatenhưng nó chỉ trên một vài sự kiện. Tôi đã tự hỏi nếu nó không được thiết lập cho một bài viết tôi có thể sử dụng post_dateđể tạo danh sách bài viết?

// 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' => '<'
        )
    )
);

là post_date một trường tùy chỉnh?
Bai Internet

Tôi đoán rằng trường công bố wordpress mặc định của nó mặc dù có thể sai? Dù bằng cách nào id cũng muốn sử dụng ngày mặc định ...
v3nt

ok vì vậy nó không phải là một trường meta trong bảng bài viết
BaiNET

Đã sửa lỗi đối số truy vấn của bạn, hy vọng rằng đã không làm sai lệch những gì bạn đang minh họa, xin vui lòng hoàn nguyên nếu cần thiết.
t31os

chúc mừng t31os - chỉnh sửa nó một lần nữa để làm cho nó rõ ràng hơn. Cần nó để chọn nội dung cũ hơn NOW bằng startDate và nếu startDate chưa được đặt, hãy sử dụng post_date mặc định của bài viết.
v3nt

Câu trả lời:


11

Nếu bạn có thể giải thích nó bằng SQL, bạn có thể truy vấn nó! Có ba nơi chúng tôi muốn thay đổi truy vấn mặc định:

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
  • Tham gia nên là một tham gia trái
  • Mệnh đề where
  • Mệnh lệnh

Join và mệnh đề where được bổ sung thông qua các _get_meta_sql()chức năng . Đầu ra được lọc, vì vậy chúng ta có thể nối vào nó:

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

Mệnh đề thứ tự được lọc qua 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;
}

Điều này cho chúng ta truy vấn SQL sau:

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

Hãy nhớ mở các bộ lọc sau khi bạn thực hiện truy vấn của mình, nếu không bạn cũng sẽ làm rối các truy vấn khác. Và nếu có thể, bạn không nên query_posts()tự gọi mình mà hãy sửa đổi truy vấn bài đăng chính được thực hiện bởi WordPress trong khi thiết lập trang.


2
Giải pháp rất thanh lịch, tôi sẽ không nghĩ đến việc sử dụng COALESCE như thế. Tôi chỉ khuyên không nên giả sử tiền tố 'wp_' mặc định và sử dụng {$ wpdb-> tiền tố} thay vào đó ...
Goldenapples 23/03

@goldenapples: Có, bạn có thể khái quát hóa nó, nhưng nó đã quá cụ thể cho truy vấn này (nó sẽ làm rối các truy vấn khác với một phần meta), mà tôi nghĩ rằng điều này là không cần thiết.
Jan Fabry

Cảm ơn Jan - đó là một mở mắt! Vẫn đang nắm bắt với wordpress và tự hỏi nơi này được gọi là gì trên trang của tôi? Và làm thế nào tôi 'un-hook' nó? tức là // $ theQuery ... sau đó <? php if (have_posts ()): while (have_posts ()): the_post (); ?>?
v3nt

@daniel: Bạn có thể đặt các chức năng trong functions.phptệp chủ đề của mình . Sau đó, ngay trước khi bạn thực hiện truy vấn, bạn đặt hai add_filter()dòng. Sau khi truy vấn bạn viết remove_filter( 'get_meta_sql', 'wpse12814_get_meta_sql' ); remove_filter( 'posts_orderby', 'wpse12814_posts_orderby' );để loại bỏ chúng một lần nữa.
Jan Fabry

ah - đó là tất cả có ý nghĩa bây giờ và làm việc quá! Rất cám ơn, điều đó sẽ hữu ích ...
v3nt

0

thử một cái gì đó dọc theo dòng:

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

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

}else{
$orderby = 'date';
}

thankx alex nhưng không chắc làm thế nào điều này có liên quan đến vòng lặp?
v3nt

doh! khi bạn truy vấn_posts (mảng ('orderby' => $ orderby))
Alex Cũ hơn

0

Một truy vấn bài viết cuộc gọi chỉ làm cho một truy vấn, không phải hai. Vì vậy, không, bạn không thể yêu cầu hai truy vấn riêng biệt và sau đó ghép các kết quả.

Hãy nhớ rằng, bạn đang chọn một số nhóm bài đăng ở đây, sau đó hiển thị chúng. Bộ đó được chọn tất cả cùng một lúc. Nếu bạn muốn nhận hai nhóm bài đăng riêng biệt và sau đó hợp nhất chúng, thì đó là điều bạn sẽ phải tự làm với get_posts hoặc tương tự.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.