Покажите все сообщения в категории с определенными сообщениями тега в вершине

Перефразируйте вопрос

Я должен заказать сообщения в цикле для моей категории car. В чем я нуждаюсь, если я посещаю страницу категории car, Мне нужны все отмеченные сообщения BMW отображаться сначала, и затем другие сообщения, не отмеченные с тегом BMW

Если мой posts_per_page набор должен показать 10 сообщений, и я нахожусь на странице один, и три из десяти сообщений отмечены BMW, затем эти три сообщения должны казаться первыми, и остальное следует тем трем сообщениям. Когда я нажимаю и иду для подкачки страниц два, то же применяется. Если я имею 5 из этих 10 отмеченных сообщений BMW, снова они должны казаться первыми перед другими 5 сообщениями.

Это возможно?

3
21.09.2014, 09:16
3 ответа

Вот упрощенная комбинация и @PieterGoosen и @ialocin прекрасных ответов при помощи loop_start рычаг:

add_action( 'loop_start', function( $q ) {
    if( $q->is_main_query() && $q->is_category( 'car' ) )
        usort( $q->posts, function( $a, $b ){
            return -1 * has_tag( 'bmw', $a ) + 1 * has_tag( 'bmw', $b );            });
}, 10, 2 );

Мы могли также использовать тот же метод для the_posts фильтр.

Обновление:

К сообщениям вида на домашней странице, первым названием категории, мы можем попробовать, например:

add_action( 'loop_start', function( $q ) {
    if( $q->is_main_query() && $q->is_home() )
        usort( $q->posts, function( $a, $b ){
            return strcasecmp( 
                get_the_category( $a->ID )[0]->name, 
                get_the_category( $b->ID )[0]->name 
            );
        });
}, 10, 2 );

где мы используем strcasecmp для нечувствительного к регистру сравнения строк.

5
19.02.2020, 22:14
  • 1
    Должен сказать, что действительно упрощен. Не может протестировать прямо сейчас, я работаю. Быстро протестирует это этим днем, когда я возвращаюсь домой, Вы знаете, что пятницы являются барбекю, регби и ночи виски :-). У меня также была та флэш-память света этим утром с помощью loop_start –  Pieter Goosen 19.09.2014, 08:15
  • 2
    Несомненно, необходимо сохранить порядок как: в пятницу, Регби, Виски..., в понедельник, WordPress ;-) –  birgire 19.09.2014, 08:20
  • 3
    Прекрасный, работая приятно от того, что я быстро протестировал. +1. Будет ожидать для вознаграждения щедрости для наблюдения то, что еще подходит. Поскольку Depeche Mode поет, "рабочая неделя прибыла в свой конец, PARTYTIME здесь снова...." Наслаждайтесь. Выписывание гуся –  Pieter Goosen 19.09.2014, 17:00
  • 4
    Это - большая песня в выходные, и я предполагаю любую песню с рок-группой, Новый Порядок имел бы смысл после работы над этим вопросом ;-) –  birgire 19.09.2014, 19:39
  • 5
    Большой услышать это работало на Вас, я обновил ответ с этой дополнительной сортировкой категории. –  birgire 21.09.2014, 12:48

Вы не можете сделать этого типа сортировки в цикле. Вы можете однако быть сделаны путем записи собственной функции

Вот мое решение: PS! PHP 5.4 потребностей +

ШАГ 1

Создайте вызванную функцию wpse161553_loop_sort($tag=''). Это будет работать с единственным тегом с основным запросом.

ШАГ 2

Необходимо получить объекты сообщения от основного запроса. Они уже доступны и могут просто быть получены доступ $wp_query->posts;. (Для полного списка доступных объектов и как получить доступ к ним, посмотрите WP_Post).

ШАГ 3

Создайте и запустите новый счетчик. Этот счетчик будет использоваться для изменения ключей массива от $wp_query->posts; позже.

ШАГ 4

Доберитесь posts_per_page опция установлена в бэкэнде. Это значение будет добавлено к счетчику для всех сообщений, который не имеет желаемого тега. Это усовершенствует все эти сообщения мимо желаемых сообщений тега

ШАГ 5

В цикле использовать has_tag() проверять каждое сообщение по желаемому тегу. Если сообщение имеет желаемый тег, продвиньте текущее встречное значение к массиву ($c) как. Если сообщение не имеет желаемого тега, продвиньте значение текущего счетчика плюс posts_per_page значение к $c

ШАГ 6

Использовать array_combine объединить два массива вместе. Недавно созданный массив $c заменит ключи массива массива сообщений

ШАГ 7

Использовать ksort отсортировать новый массив, созданный с array_combine согласно новым ключам. Это теперь отсортирует массив так, чтобы сообщения были отсортированы по дате сообщения, и также, сообщение от желаемого тега будет казаться первым, затем остальная часть сообщений

Шаг 8

Использовать array-values сбрасывать ключи назад для запуска в 0 и инкремент численно одним

ШАГ 9

Перемотайте цикл так, чтобы мы могли повторно выполнить цикл

ШАГ 10

Сбросьте исходный массив внутри $wp_query->posts и замените его новым созданным массивом. $wp_query->posts будет теперь содержать массив с недавно заказанным порядком сообщения

ВСЕ ВМЕСТЕ ТЕПЕРЬ!!

Следующий код входит в Ваш functions.php

function wpse161553_loop_sort($tag='') {
    global $wp_query;
    $posts = $wp_query->posts; // Gets all post data from the main query

    $c = []; // Going to hold an array of new keys for later use
    if ( have_posts() ) {
        $count = 0; //Start the counter
        $ppp = get_option('posts_per_page'); // Gets the backend posts per page option set. Will be used in conjustion with the counter

        while ( have_posts() ) {
            the_post();
                if( '' != $tag && has_tag($tag)) { // This will be the tag to test against, your desired tag
                    $c[] = $count++;
                }else{
                    $c[] = $ppp + $count++; // Adds posts per page value to each count to advance posts without desired tag past desired tag
                }
        }
    } 

    $posts_reordered  = array_combine( $c, $posts ); // Reset each post from main query's key with the new keys created by $c
        $posts_sorted = ksort($posts_reordered); // Sort the new array according to key
    $posts_reordered  = array_values($posts_reordered); // Reset keys to start at zero and increment by one

    rewind_posts(); // Reset the loop so we can run the loop again

    unset($wp_query->posts); //unset the original $wp_query->posts object array
    $wp_query->posts = $posts_reordered; // Set $wp_query->posts to the new reordered array

}

КАК ЭТО БУДЕТ ИСПОЛЬЗОВАТЬСЯ

В Вашем category.php, или в этом отношении, любой шаблон, вставляют следующее чуть выше цикла. Вы не должны изменять ничто больше

wpse161553_loop_sort( 'NAME OF THE TAG TO APPEAR FIRST' );

где NAME OF THE TAG TO APPEAR FIRST название желаемого тега, какие сообщения будут казаться первыми

3
19.02.2020, 22:14

Просто быстрый обрисованный в общих чертах проект идеи, поэтому остерегайтесь, я не думал и протестировал это через полностью. Я уверен, хотя это можно выполнить действия сортировки этот путь. Хорошо, то, что я думал, почему не сцепление в the_posts и используйте usort сделать сортировку. Все остальные, особенно условные выражения должны только удостовериться, что это не выполняется на каждом запросе и зависит от фактического варианта использования, так, чтобы было пригодно соответственно.

add_action(
    'the_posts',
    'wpse161553_posts_with_tags_on_top_of_category',
    10,
    2
);
function wpse161553_posts_with_tags_on_top_of_category(
    $posts,
    $wp_query
) {
    // we want this for one specific category
    $the_category = 'abc';
    // we want the post with this tag on top 
    $the_tag      = 'xyz';

    if (
        $wp_query->is_main_query()
        && is_category( $the_category )
    ) {
        // getting an array of post ids from category with tag
        $posts_with_tag = new WP_Query(
            array(
                'category_name' => $the_category,
                'tag'           => $the_tag,
                'fields'        => 'ids'
            )
        );  
        // performing usort on referenced posts object
        usort(
            $posts,
            function (
                $post
            ) use (
                $posts_with_tag
            ) {
                // puts posts from the $posts_with_tag->posts array to the top
                if(
                    in_array (
                        $post->ID,
                        (array) $posts_with_tag->posts 
                     )
                ) {
                    return -1;
                } else {
                    return 1;
                }
            }
        );
    }

    return $posts;
} 
2
19.02.2020, 22:14
  • 1
    Это могло бы быть возможно к persuite это этот путь, но это собирается взять некоторую работу все же. Это просто в настоящее время сортирует текущие сообщения в цикле от в последний раз до первого, так в основном он инвертирует :-) –  Pieter Goosen 18.09.2014, 17:23
  • 2
    Ну, щедрость в течение семи дней, и я думаю, что Ваша идея допустима. Я хотел бы видеть то, что выходит из этого, даже если это просто инвертирует сообщения. Выбор ваше дело также, если Вы захотите работать с ним :-) –  Pieter Goosen 18.09.2014, 18:30
  • 3
    , я форматировал Ваш код, чтобы быть более читаемым, :-). Кроме того, я изменился (если Вы не возражаете), $wp_query->query['category_name'] == $the_category кому: is_category( $the_category ) поскольку оригинал повредил мой бэкэнд и запросы конца ветви. Ваш код предназначается для корректной страницы, это - просто проблема сортировки теперь. –  Pieter Goosen 18.09.2014, 21:01
  • 4
    Мало того, что я не возражаю, я действительно ценю его! И если я делаю вещи второпях, я все еще делаю весь неправильный материал, так хорошая вещь, которой Вы заменили мою закалку $wp_query. Об удобочитаемости я предполагаю, что это довольно субъективно, мне лично нравится разделять параметры на дополнительных строках и находить это довольно читаемым, но я также не возражаю против того изменения. @PieterGoosen –  Nicolai 18.09.2014, 21:19
  • 5
    , Измененный это немного, дал ему быстрый тест, кажется, работает даже с разбиением на страницы. Извините за "неправильное" форматирование снова, это, как я настроил свой IDE, чтобы сделать это для меня. Я слишком ленив для переформатирования, но не стесняюсь делать это. @PieterGoosen –  Nicolai 18.09.2014, 22:37

Теги

Похожие вопросы