it-swarm.com.de

Besteuerung der Abfrage X Anzahl der Beiträge, die zuerst nach Tag und dann nach Kategorie verknüpft sind, wenn die Anzahl der Beiträge, die mit dem Tag zusammenhängen, nicht ausreicht

Frage

Wie kann man zuerst tag-bezogene Beiträge ausgeben, dann, wenn es weniger als 4 tag-bezogene Beiträge gibt, den Rest der 4 Stellen mit kategoriebezogenen Beiträgen füllen?

Szenario

Manchmal hat ein Beitrag nur sehr wenige Tags, oder die Tags, mit denen er gekennzeichnet ist, haben nur sehr wenige Beiträge. Bei der Ausgabe von "verwandten Beiträgen nach Tags" ist der Bereich entweder mit 1 oder 2 Beiträgen sehr spärlich oder komplett leer.

Um dieses Problem zu lösen, ist es hilfreich, Beiträge aus verwandten Kategorien anzuzeigen, wenn nicht genügend tag-bezogene Beiträge vorhanden sind, um den posts_per_page => X zu erfüllen.

So etwas in der Art:


Szenario A - Wenn mehr als 4 tagbezogene Posts vorhanden sind, dann:

Related Posts:

Show the below posts:

1. tag-related post #1
2. tag-related post #2
3. tag-related post #3
4. tag-related post #4

Do Not show the below posts:

5. tag-related post #5
6. tag-related post #6
7. tag-related post #7
...

Szenario B - Wenn nur 2 tagbezogene Posts vorhanden sind, gilt Folgendes:

Related Posts:

Show the below posts:

1. tag-related post #1
2. tag-related post #2  
3. category-related post #1
4. category-related post #2

Do Not show the below posts:

5. category-related post #3
6. category-related post #4
7. category-related post #5
...

Was ich versucht habe

Die Steuerabfrage, die ich verwende:

// start of the tax_query arguments
$args = array( 'posts_per_page'=>4, 'post__not_in' => array($post->ID), 'tax_query' => array( 'relation' => 'OR' ) );

// get current post tags
$tags = wp_get_object_terms( $post->ID, 'post_tag', array( 'fields' => 'ids' ) );

if ( !empty( $tags ) ) {
    $args['tax_query'][] = array(
        'taxonomy' => 'post_tag',
        'field'    => 'id',
        'terms'    => $tags
    );
}

// get current post categories
$categories = wp_get_object_terms( $post->ID, 'category', array( 'fields' => 'ids' ) );

if ( !empty( $categories ) ) {
    $args['tax_query'][] = array(
        'taxonomy' => 'category',
        'field'    => 'id',
        'terms'    => $categories
    );
}

// the query
$related_query = new WP_Query( $args );

Soweit ich weiß, lautet die Steuerabfrage "Beiträge in denselben Kategorien abrufen, dann Beiträge mit denselben Tags abrufen und dann Beiträge ausgeben, bis 4 auf dem Bildschirm angezeigt werden."

Es gibt jedoch weiterhin zuerst Kategorie-Posts aus (von denen es viele gibt), die die 4 Posts auf dem Bildschirm-Regel erfüllen und die wichtigsten tag-bezogenen Posts weglassen. Ich habe versucht, den Code zu verschieben und AND anstelle von OR zu verwenden, was nicht funktionierte und für mich sowieso keinen Sinn ergab.

Ich habe auch folgende Posts gesehen: WordPress - Erstellen einer Liste von Posts, die nach Tag und dann nach Kategorie gefiltert wurden und Abfragen von Posts in Wordpress nach Tag und Kategorie , aber es geht darum, eine Liste von Posts auszugeben, die gefiltert wurden nach tag UND kategorie. Ich benötige Posts, die zuerst nach Tags verknüpft sind, und bei 4 oder mehr werden nur die Top-4 ausgegeben. Bei weniger als 4 werden bis zu so viele kategoriebezogene Posts ausgegeben, dass die 4 Posts-Kriterien erfüllt werden.

Ich verstehe die Anfrage und/oder das Problem eindeutig falsch, daher wäre jede Hilfe willkommen.

LÖSUNG

Peters Lösung funktioniert perfekt - danke Peter!

Ich habe es ein bisschen für meine eigenen Zwecke weiterentwickelt und unter Verwendung Ihres beeindruckend kommentierten Codes konnte ich auch "Aktuelle Beiträge" von dieser Abfrage ausschließen - woohoo!

3
Andre Bulatov

Sie können dies nicht in einer Abfrage tun. Dies ist ein bisschen zu weit fortgeschritten für das, was WP_Query zu diesem Zeitpunkt tun kann. Wir müssen mindestens zwei ( Ich werde 3 ) Abfragen hier ausführen, um zu erreichen, was Sie wollen

ERSTE FRAGE

Die erste Abfrage fragt nach Beiträgen nach post_tag, wobei auch der aktuelle Beitrag ausgeschlossen wird. Wir erhalten nur Post-IDs

ZWEITE FRAGE

Diese Abfrage behandelt die "Auffüll" -Posts, die aus der Taxonomie category stammen. Damit diese Abfrage erfolgreich ist, benötigen wir Folgendes

  • Schließen Sie den aktuellen Beitrag und die Beiträge aus der ersten Abfrage aus, um doppelte Beiträge zu vermeiden

  • Holen Sie sich die Anzahl der Posts in der ersten Abfrage, subtrahieren Sie diese von 4 und verwenden Sie diese Differenz, um die Anzahl der Posts festzulegen, die von dieser Abfrage abgerufen werden sollen

Wir bekommen hier auch nur Post-IDs

DRITTE FRAGE

Um die Integrität des Abfrageobjekts zu erhalten, werden alle IDs aus der vorherigen Abfrage kombiniert und die endgültigen Post-Objekte abgefragt. Sie denken vielleicht, dass dies teuer ist, aber es ist nicht. Da die ersten beiden Abfragen get_posts() verwenden und nur Post-IDs erhalten, sind sie wirklich superschnell. Indem wir nur IDs abfragen, aktualisieren wir auch keine Caches, wodurch diese Abfragen noch schneller werden

LÖSUNG

Ich bevorzuge es, eine Funktion für so große Teile wie Code zu erstellen, damit meine Vorlagen sauber bleiben. Bitte beachten Sie Folgendes ist ungetestet und erfordert PHP 5.4

function get_max_related_posts( $taxonomy_1 = 'post_tag', $taxonomy_2 = 'category', $total_posts = 4 )
{
    // First, make sure we are on a single page, if not, bail
    if ( !is_single() )
        return false;

    // Sanitize and vaidate our incoming data
    if ( 'post_tag' !== $taxonomy_1 ) {
        $taxonomy_1 = filter_var( $taxonomy_1, FILTER_SANITIZE_STRING );
        if ( !taxonomy_exists( $taxonomy_1 ) )
            return false;
    }

    if ( 'category' !== $taxonomy_2 ) {
        $taxonomy_2 = filter_var( $taxonomy_2, FILTER_SANITIZE_STRING );
        if ( !taxonomy_exists( $taxonomy_2 ) )
            return false;
    }

    if ( 4 !== $total_posts ) {
        $total_posts = filter_var( $total_posts, FILTER_VALIDATE_INT );
            if ( !$total_posts )
                return false;
    }

    // Everything checks out and is sanitized, lets get the current post
    $current_post = sanitize_post( $GLOBALS['wp_the_query']->get_queried_object() );

    // Lets get the first taxonomy's terms belonging to the post
    $terms_1 = get_the_terms( $current_post, $taxonomy_1 );

    // Set a varaible to hold the post count from first query
    $count = 0;
    // Set a variable to hold the results from query 1
    $q_1   = [];

    // Make sure we have terms
    if ( $terms_1 ) {
        // Lets get the term ID's
        $term_1_ids = wp_list_pluck( $terms_1, 'term_id' );

        // Lets build the query to get related posts
        $args_1 = [
            'post_type'      => $current_post->post_type,
            'post__not_in'   => [$current_post->ID],
            'posts_per_page' => $total_posts,
            'fields'         => 'ids',
            'tax_query'      => [
                [
                    'taxonomy'         => $taxonomy_1,
                    'terms'            => $term_1_ids,
                    'include_children' => false
                ]
            ],
        ];
        $q_1 = get_posts( $args_1 );
        // Count the total amount of posts
        $q_1_count = count( $q_1 );

        // Update our counter
        $count = $q_1_count;
    }

    // We will now run the second query if $count is less than $total_posts
    if ( $count < $total_posts ) {
        $terms_2 = get_the_terms( $current_post, $taxonomy_2 );
        // Make sure we have terms
        if ( $terms_2 ) {
            // Lets get the term ID's
            $term_2_ids = wp_list_pluck( $terms_2, 'term_id' );

            // Calculate the amount of post to get
            $diff = $total_posts - $count;

            // Create an array of post ID's to exclude
            if ( $q_1 ) {
                $exclude = array_merge( [$current_post->ID], $q_1 );
            } else {
                $exclude = [$current_post->ID];
            }

            $args_2 = [
                'post_type'      => $current_post->post_type,
                'post__not_in'   => $exclude,
                'posts_per_page' => $diff,
                'fields'         => 'ids',
                'tax_query'      => [
                    [
                        'taxonomy'         => $taxonomy_2,
                        'terms'            => $term_2_ids,
                        'include_children' => false
                    ]
                ],
            ];
            $q_2 = get_posts( $args_2 );

            if ( $q_2 ) {
                // Merge the two results into one array of ID's
                $q_1 = array_merge( $q_1, $q_2 );
            }
        }
    }

    // Make sure we have an array of ID's
    if ( !$q_1 )
        return false;

    // Run our last query, and output the results
    $final_args = [
        'ignore_sticky_posts' => 1,
        'post_type'           => $current_post->post_type,
        'posts_per_page'      => count( $q_1 ),
        'post__in'            => $q_1,
        'order'               => 'ASC',
        'orderby'             => 'post__in',
        'suppress_filters'    => true,
        'no_found_rows'       => true
    ];
    $final_query = new WP_Query( $final_args );

    return $final_query;
}

Sie können die Funktion jetzt wie folgt in Ihrer einzelnen Vorlage verwenden

$query = get_max_related_posts();
if ( $query ) {

    while ( $query->have_posts() ) {
        $query->the_post();

            echo get_the_title() . '</br>';

    }
    wp_reset_postdata();
}

EINIGE ANMERKUNGEN

  • Die Standardeinstellungen sind für die drei Parameter bereits auf post_tag, category und 4 festgelegt, sodass Sie beim Aufruf der Funktion keine Werte an die Funktion übergeben müssen

  • Wenn Sie die Taxonomien vertauschen oder andere Taxonomien festlegen oder die Beiträge pro Seite auf einen anderen Wert als 4 festlegen müssen, übergeben Sie sie einfach in der richtigen Reihenfolge an die Funktion

    $query = get_max_related_posts( 'tax_1', 'tax_2', 6 );
    
3
Pieter Goosen