Mostrar todas las publicaciones en la categoría, con etiquetas específicas en la parte superior

3

Replantear pregunta

Necesito ordenar publicaciones dentro del bucle para mi categoría car . Lo que necesito, si visito la página de categoría de car , necesito que todas las publicaciones etiquetadas como BMW se muestren primero, y luego las otras publicaciones no etiquetadas con la etiqueta BMW

Si mi posts_per_page está configurado para mostrar 10 publicaciones, y estoy en la página uno, y tres de las diez publicaciones están etiquetadas como BMW , estas tres publicaciones deben aparecer primero, y el resto sigue esas tres publicaciones. . Cuando hago clic y voy a la página dos, se aplica lo mismo. Si tengo 5 de estos 10 mensajes etiquetados BMW , deben aparecer primero antes que los otros 5 mensajes.

¿Es eso posible?

    
pregunta PreeT 16.09.2014 - 10:01

3 respuestas

5

Aquí hay una combinación simplificada de ambas respuestas finas @PieterGoosen y @ialocin usando el enganche 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 );

También podríamos usar el mismo método para el filtro the_posts .

Actualizar:

Para ordenar los mensajes en la página de inicio, por el nombre de la primera categoría, podemos intentar, por ejemplo:

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

donde usamos strcasecmp para la comparación de cadenas que no distingue entre mayúsculas y minúsculas.

    
respondido por el birgire 19.09.2014 - 06:40
3

No puedes hacer este tipo de clasificación dentro del bucle. Sin embargo, puedes hacerlo escribiendo tu propia función

Aquí está mi solución: ¡PS! Necesita PHP 5.4+

PASO 1

Crea una función llamada wpse161553_loop_sort($tag='') . Esto funcionará con una sola etiqueta con la consulta principal.

PASO 2

Es necesario obtener los objetos de publicación de la consulta principal. Ya están disponibles y solo se puede acceder a ellos mediante $wp_query->posts; . (Para obtener una lista completa de los objetos disponibles y cómo acceder a ellos, consulte WP_Post ).

PASO 3

Crea e inicia un nuevo contador. Este contador se utilizará para alterar las claves de la matriz de $wp_query->posts; más adelante.

PASO 4

Obtenga la opción posts_per_page establecida en el back-end. Este valor se agregará al contador para todas las publicaciones que no tengan la etiqueta deseada. Esto hará avanzar todas estas publicaciones más allá de las publicaciones de etiqueta deseadas

PASO 5

Dentro del bucle, usa has_tag() para comparar cada publicación con la etiqueta deseada. Si una publicación tiene una etiqueta deseada, presione el valor del contador actual a una matriz ( $c ) como está. Si una publicación no tiene la etiqueta deseada, presione el valor del contador actual más el valor posts_per_page a $c

PASO 6

Use array_combine para combinar las dos matrices juntas. La nueva matriz creada $c reemplazará las claves de matriz de la matriz de publicaciones

STEP 7

Use ksort para ordenar la nueva matriz creada con array_combine de acuerdo con las nuevas claves . Ahora esto ordenará la matriz para que las publicaciones se ordenen por fecha de publicación, y también, la publicación de la etiqueta deseada aparecerá primero, luego el resto de las publicaciones

Paso 8

Use array-values para restablecer las claves de nuevo para comenzar en 0 e incrementar numéricamente por uno

PASO 9

Rebobina el bucle para que podamos volver a ejecutarlo

PASO 10

Desactive la matriz original dentro de $wp_query->posts y reemplácela con la nueva matriz creada. $wp_query->posts ahora tendrá una matriz con el nuevo orden de envío ordenado

¡TODOS JUNTOS AHORA!

El siguiente código entra en tus funciones.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

}

CÓMO SE UTILIZARÁ

En su category.php, o para el caso, en cualquier plantilla, pegue lo siguiente justo encima del bucle. No necesitas cambiar nada más

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

donde NAME OF THE TAG TO APPEAR FIRST es el nombre de la etiqueta deseada en la que aparecerán primero las publicaciones

    
respondido por el Pieter Goosen 16.09.2014 - 15:25
2

Solo un borrador rápido de una idea, así que ten cuidado, no lo he pensado y probado completamente. Sin embargo, estoy seguro de que puedes realizar acciones de clasificación de esta manera. Ok, lo que estaba pensando es, ¿por qué no enlazar con the_posts y usar usort para hacer la clasificación? Todo lo demás, especialmente los condicionales, son solo para asegurarse de que esto no se realice en todas las consultas y depende del caso de uso real, por lo que debe ajustarse en consecuencia.

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

Lea otras preguntas en las etiquetas