Exibir todas as postagens na categoria, com postagens de tag específicas na parte superior

3

Reformule a pergunta

Eu preciso solicitar postagens dentro do loop para minha categoria car . Do que preciso, se eu visitar a página da categoria de car , preciso que todas as postagens marcadas com BMW sejam exibidas primeiro e, depois, as outras postagens não marcadas com a tag BMW

Se meu posts_per_page estiver definido para exibir 10 postagens e eu estiver na primeira página, e três das dez postagens forem marcadas com BMW , essas três postagens deverão aparecer primeiro e o restante seguirá essas três postagens . Quando clico e vou para a página dois, o mesmo se aplica. Se eu tiver 5 dessas 10 postagens marcadas com BMW , elas devem aparecer primeiro antes das outras 5 postagens.

Isso é possível?

    
por PreeT 16.09.2014 / 10:01

3 respostas

5

Aqui está uma combinação simplificada de ambas as respostas @PieterGoosen e @ialocin usando o loop_start hook:

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

Também poderíamos usar o mesmo método para o filtro the_posts .

Atualização:

Para classificar postagens na página inicial, pelo nome da primeira categoria, podemos tentar, por exemplo:

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

onde usamos strcasecmp para comparação de cadeias sem distinção entre maiúsculas e minúsculas.

    
por birgire 19.09.2014 / 06:40
3

Você não pode fazer esse tipo de classificação dentro do loop. Você pode, no entanto, ser feito escrevendo sua própria função

Aqui está a minha solução: PS! Precisa de PHP 5.4 +

PASSO 1

Crie uma função chamada wpse161553_loop_sort($tag='') . Isso funcionará com uma única tag com a consulta principal.

PASSO 2

Você precisa obter os objetos de postagem da consulta principal. Eles já estão disponíveis e podem ser acessados apenas por $wp_query->posts; . (Para obter uma lista completa dos objetos disponíveis e como acessá-los, consulte WP_Post ).

PASSO 3

Crie e inicie um novo contador. Este contador será usado para alterar as chaves do array a partir de $wp_query->posts; mais tarde.

PASSO 4

Obtenha a opção posts_per_page definida no back end. Esse valor será adicionado ao contador de todas as postagens que não tenham a tag desejada. Isso avança todas essas postagens além das postagens de tag desejadas

PASSO 5

Dentro do loop, use has_tag() para verificar cada postagem em relação à tag desejada. Se uma postagem tiver uma tag desejada, envie o valor atual do contador para uma matriz ( $c ) como está. Se uma postagem não tiver a tag desejada, envie o valor do contador atual mais o valor posts_per_page para $c

PASSO 6

Use array_combine para combinar as duas matrizes juntas. A matriz recém-criada $c substituirá as chaves da matriz da matriz de postagens

PASSO 7

Use ksort para classificar a nova matriz criada com array_combine de acordo com as novas chaves . Isso agora classificará a matriz para que as postagens sejam classificadas por data de postagem e, também, a postagem da tag desejada aparecerá primeiro e, em seguida, o restante das postagens

Etapa 8

Use array-values para redefinir as chaves para começar em 0 e incrementar numericamente por um

PASSO 9

Rebobine o loop para que possamos executar novamente o loop

PASSO 10

Desmarque a matriz original dentro de $wp_query->posts e substitua-a pela nova matriz criada. $wp_query->posts agora conterá uma matriz com a ordem de encomenda recém-ordenada

TODOS JUNTOS AGORA !!

O seguinte código vai para o seu 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

}

COMO SERÁ UTILIZADO

Em sua categoria.php, ou em qualquer modelo, cole o seguinte logo acima do loop. Você não precisa mudar mais nada

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

onde NAME OF THE TAG TO APPEAR FIRST é o nome da tag desejada que as postagens aparecerão primeiro

    
por Pieter Goosen 16.09.2014 / 15:25
2

Apenas um rascunho rápido de uma ideia, então cuidado, eu não pensei e testei isso completamente. Estou certo de que você pode executar ações de classificação dessa maneira. Ok, o que eu estava pensando é, por que não ligar em the_posts e usar usort para fazer a classificação. Todo o resto, especialmente as condicionais, são apenas para garantir que isso não seja executado em todas as consultas e depende do caso de uso real, portanto, isso deve ser adequado.

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;
} 
    
por Nicolai 18.09.2014 / 16:12