Чи можу я виключити публікацію за допомогою мета-ключа за допомогою функції pre_get_posts?


24

Я бачу, що багато людей вважають за краще використовувати pre_get_postsгачок замість query_posts. Код внизу працює і показує всі повідомлення, у яких мета-ключ "показаний"

function show_featured_posts ( $query ) {
    if ( $query->is_main_query() ) {
       $query->set( 'meta_key', 'featured' );
       $query->set( 'meta_value', 'yes' );
    }
}

add_action( 'pre_get_posts', 'show_featured_posts' );

Але я хочу, щоб публікації, які містять featuredмета_кей, були виключені з основного запиту. Чи існує простий спосіб для цього?

Відповіді:


33

Я бачу, що багато людей вважають за краще використовувати гачок pre_get_posts замість query_posts

Так!

Таким чином, pre_get_postsфільтруйте WP_Queryоб'єкт, що означає все, що ви могли зробити через query_posts()вас, можна зробити через $query->set()і $query->get(). Зокрема, ми можемо скористатися meta_queryатрибутом (див. Кодекс ):

$meta_query = array(
                 array(
                    'key'=>'featured',
                    'value'=>'yes',
                    'compare'=>'!=',
                 ),
);
$query->set('meta_query',$meta_query);

Але .. це замінює оригінальний "мета-запит" (якщо він був). Тому, якщо ви не хочете повністю замінити оригінальний мета-запит, пропоную:

//Get original meta query
$meta_query = $query->get('meta_query');

//Add our meta query to the original meta queries
$meta_query[] = array(
                    'key'=>'featured',
                    'value'=>'yes',
                    'compare'=>'!=',
                );
$query->set('meta_query',$meta_query);

Таким чином ми додаємо наш мета-запит поряд із існуючими мета-запитами.

Ви можете / не хочете встановлювати relationвластивість $meta_queryдо ANDабо OR(повертати повідомлення, які задовольняють усі або принаймні один мета-запит).

* Примітка. Цей тип запиту повертає публікації з мета-клавішею 'Featured', але значення якого немає yes. Він не включатиме публікації, де мета-ключ "показаний" не існує. Ви зможете це зробити в 3.5 .


Тож немає способу перевірити, чи існує мета-ключ для публікації чи ні / порожній чи ні? Мені доведеться чекати 3,5. потім. Дякуємо за Ваш відповідь.
Карлайл

Я просто створять мета-вікно з Yesі Noпараметрами, і "Ні" буде вибрано за замовчуванням. Коли я хочу розмістити публікацію, я виберу Yes. Однак я хочу, щоб останні 5 публікацій не відображалися, а інші продовжували відображатися в головному запиті. Я не хочу повертатись і змінювати вибір кожен раз, тому мені доводиться знаходити спосіб виключити лише останні останні лише 5 публікацій. Я бачу багато подібних питань щодо stackexchange, і там повинен бути простий спосіб керувати цими популярними публікаціями. (спосіб, який не впливає на загальну ефективність, не створює багато запитів або не потребує змішаних запитів sql)
Carlisle

BTW Я не впевнений, чи гарна ідея створити додатковий meta_key з Yesабо Noзначенням для всіх публікацій. Було б чудово виключити ті посади, у яких просто бракує featuredключа.
Карлайл

Ця функція просто вийшла з ладу на моєму сайті після оновлення до PHP 7, внаслідок Uncaught Error: [] operator not supported for stringsчого meta_queryбуло видано помилку, оскільки оригінал повертався як нуль. Ви можете отримати навколо нього, падаючи назад в порожній масив , якщо він не існує перемикання з $meta_query = $query->get('meta_query');для $meta_query = ( is_array( $query->get('meta_query') ) ) ? $query->get('meta_query') : [];.
Кевін Нугент

2

Я хочу опублікувати своє тимчасове рішення для розміщених постів на випадок, якщо хтось може ним скористатися. Я тут не використовую pre_get_postsгачок, але не query_postsбудь-який. Проблема полягає в тому, що я повинен грати з основним запитом і повинен запускати частину запиту sql. Я був би радий, якби будь-який експерт міг перевірити код і повідомити мені, чи це нормально і чи не викличе проблем із ефективністю. Також буде чудово, якщо хтось матиме кращий підхід і поділиться ним із нами.

Створення популярних запитів публікацій

<?php 

$featured_query = new WP_query( array(
    'meta_key'       =>'featured', 
    'meta_value'     =>'yes', 
    'posts_per_page' => 5, 
    'no_found_rows'  => true
    )
);

while ($featured_query->have_posts()) : 

    $featured_query->the_post(); 
    //Stuff...

endwhile; 
wp_reset_postdata(); 

?>

Створіть основний запит, виключіть публікації, у яких є мета-ключ, обмежте виключення на 5 останніх публікацій та покажіть усі інші.

<?php 

$excludeposts = $wpdb->get_col( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'featured' AND meta_value != '' ORDER BY post_id DESC LIMIT 0, 5" );

$main_query = new WP_Query( array(
    'post__not_in' => $excludeposts, 
    'paged' => $paged 
    ) 
);  

while ($main_query->have_posts()) : 

    $main_query->the_post();
    //Stuff...

endwhile;

?>

0

У відповідь @Carlisle, якщо ви хочете виключити останні 5 останніх публікацій, позначених як показані, ви можете зробити наступне. Змініть posts_per_page, скільки ви хочете виключити, а meta_query на те, як ви визначаєте категорію, що пропонується.

function cmp_exclude_featured_posts($query) {
    $exclude = array();  //Create empty array for post ids to exclude
    if ( $query->is_main_query() ) {
            $featured = get_posts(array(
                'post_type' => 'post',
                'meta_query' => array(
                    array(
                        'key' => 'featured',
                        'value' => '1',
                        'compare' => '==',
                    ),
                ),
                'posts_per_page' => 2
            ));

            foreach($featured as $hide) {
                $exclude[] = $hide->ID;
            }   

            $query->set('post__not_in', $exclude);
        }
}

add_filter( 'pre_get_posts', 'cmp_exclude_featured_posts' );
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.