it-swarm.com.de

Sticky Posts auf Homepage, Suche, Tag und Archiven ohne Plugin

Ich habe heute eine Frage. Ich bin auf der Suche nach einer Lösung, um klebrige Posts auf meiner Website verfügbar zu machen. Aber ich habe es gerade auf der Homepage mit dem folgenden Code zum Laufen gebracht.

function wpb_latest_sticky() { 

/* Get all sticky posts */
$sticky = get_option( 'sticky_posts' );

/* Sort the stickies with the newest ones at the top */
rsort( $sticky );

/* Get the 5 newest stickies (change 5 for a different number) */
$sticky = array_slice( $sticky, 0, 5 );

/* Query sticky posts */
$the_query = new WP_Query( array( 'post__in' => $sticky, 'ignore_sticky_posts' => 1 ) );
// The Loop
if ( $the_query->have_posts() ) {
    $return .= '<ul>';
    while ( $the_query->have_posts() ) {
        $the_query->the_post();
        $return .= '<li><a href="' .get_permalink(). '" title="'  . get_the_title() . '">' . get_the_title() . '</a><br />' . get_the_excerpt(). '</li>';

    }
    $return .= '</ul>';

} else {
    // no posts found
}
/* Restore original Post Data */
wp_reset_postdata();

return $return; 

} 
add_shortcode('latest_stickies', 'wpb_latest_sticky');

Ich habe darüber nachgedacht, den Haftnotizbeitrag so zu gestalten, dass er auch in Suche, Tag und Kategorie angezeigt wird.

Irgendeine Lösungsmöglichkeit? Vielen Dank!

3
Jornes

Dieselbe genaue Frage wurde Anfang dieser Woche oder über das Wochenende gestellt, und ich musste nachdenken. Hier ist die Idee, die ich mir ausgedacht habe.

Wenn Sie sich den Quellcode der Klasse WP_Query ansehen, werden Sie feststellen, dass nur auf der ersten Seite der Homepage Haftnotizen hinzugefügt werden. Es wird auch kein Filter bereitgestellt, um dieses Verhalten zu ändern und die erforderlichen Vorlagen nach Ihren Wünschen festzulegen.

Es gibt viele Möglichkeiten, um Haftnotizen in anderen Vorlagen über Widgets, benutzerdefinierte Abfragen, Shortcodes (die ich nicht empfehlen werde, da die Verwendung von do_shortcode() langsamer ist als die Verwendung der Funktion selbst) oder benutzerdefinierte Funktionen anzuzeigen, wenn Sie sie benötigen. Ich habe mich für die Verwendung von the_posts filter und pre_get_posts action entschieden.

HIER IST WIE:

  • Holen Sie sich die Post-IDs als Haftnotizen mit get_option( 'sticky_posts' )

  • Entfernen Sie diese Beiträge aus der Hauptabfrage mit pre_get_posts. Da Stickies auf der Homepage enthalten sind, schließen wir die Homepage aus. Wir werden auch normale Seiten ausschließen

  • Führen Sie in einer benutzerdefinierten Funktion eine benutzerdefinierte Abfrage mit get_posts aus, um die Posts als Sticky-Posts festzulegen.

  • Füge das zurückgegebene Array von Sticky Posts mit den aktuell zurückgegebenen Posts der Hauptabfrage mit array_merge zusammen.

  • Binden Sie diese benutzerdefinierte Funktion in den the_posts-Filter ein

Hier ist der Code: ( Erfordert PHP 5.4+ )

add_action( 'pre_get_posts', function ( $q )
{
    if (    !is_admin()
         && $q->is_main_query()
         && !$q->is_home()
         && !$q->is_page()
    ) {

        $q->set( 'post__not_in', get_option( 'sticky_posts' ) );

        if ( !$q->is_paged() ) {
            add_filter( 'the_posts', function ( $posts )
            {
                $stickies = get_posts( ['post__in' => get_option( 'sticky_posts' ), 'nopaging' => true] );

                $posts = array_merge( $stickies, $posts );

                return $posts;

            }, 10, 2);
        }

    }
});
3
Pieter Goosen

Ich brauchte einige Modifikationen (Original siehe Pieters Antwort), damit es nur auf Kategorieseiten funktioniert. Diese Lösung zeigt alle Haftnotizen der aktuellen Kategorie (und der untergeordneten Kategorien) an, jedoch nicht auf Such-, Tag- und Einzelseiten:

add_action( 'pre_get_posts', function ( $q ) {
    if ( !is_admin()
         && $q->is_main_query()
         && !$q->is_home()
         && !$q->is_tag()
         && !$q->is_search()
         && !$q->is_page()
         && !$q->is_single()
    ) {

      function is_existing_cat($q_catName) {
           $existingCats = get_categories();
           $isExistingCat = false;

           foreach ($existingCats as $cat) {
                if ($cat->name == $q_catName) {
                     $isExistingCat = true;
                }
           }

           return $isExistingCat;
      }

        if ($q->is_category() && !$q->is_paged() && is_existing_cat($q->query['category_name'])) {

            $q->set( 'post__not_in', get_option( 'sticky_posts' ) );

            add_filter( 'the_posts', function ( $posts ) {
                $catName = get_category(get_query_var('cat'))->name;
                $catID = get_cat_ID($catName);

                if ( !empty(get_option( 'sticky_posts' )) ) {
                    $stickies = get_posts( [
                        'category' => $catID,
                        'post__in' => get_option( 'sticky_posts' )
                    ] );

                    $posts = array_merge( $stickies, $posts );
                }

                return $posts;

            }, 10, 2);
        }
    }
});

Ich habe eine Funktion hinzugefügt, um zu überprüfen, ob es sich bei der Kategorie um eine vorhandene Kategorie handelt, da ich auf das Problem gestoßen bin, dass ich anstelle der erwarteten 404.php auf die category.php weitergeleitet wurde. Links wie /existing-cat/not-existing-post haben funktioniert, Links wie /not-existing-post-or-page-or-cat jedoch nicht.

Wenn Sie eine CSS-Klasse für diesen Beitrag benötigen, fügen Sie diesen Code zum PHP -Teil der Vorlage hinzu, der den Inhalt des Beitrags anzeigt (in sechsundzwanzig zum Beispiel: template-parts/content.php).

<?php
if (is_sticky()) {
    $stickyClass = 'sticky';
} else {
    $stickyClass = '';
}
?>

Dann fügen Sie diese Klasse zu den CSS-Klassen der post post_class($stickyClass); hinzu (diese Funktion fügt dem HTML-Element das class-Attribut mit einigen Klassen und Ihrer hinzugefügten Klasse hinzu). Möglicherweise finden Sie diese Funktion bereits im Artikel:

<article id="post-<?php the_ID(); ?>" <?php post_class($stickyClass); ?>>
    ...
</article><!-- #post-## -->
1
RedNails

Die Antwort von Pieter funktioniert, aber sie zeigt all sticky posts auch auf Seiten an, auf denen gefilterte Posts angezeigt werden sollen (z. B. für eine bestimmte Kategorie).

Folgendes funktioniert für mich. Wenn Sie dies zu functions.php hinzufügen, werden nur Stickies innerhalb der Teilmenge der gefilterten Posts angezeigt:

add_filter('the_posts', 'bump_sticky_posts_to_top');
function bump_sticky_posts_to_top($posts) {
    $stickies = array();
    foreach($posts as $i => $post) {
        if(is_sticky($post->ID)) {
            $stickies[] = $post;
            unset($posts[$i]);
        }
    }
    return array_merge($stickies, $posts);

(Credits: http://Pastebin.com/Y5jVrKg4 , mit einer kleinen Änderung, um ein Warnung: array_merge () [function.array-merge]: Argument # 1 ist kein Array in Zeile 9 error)

Es gibt jedoch einen großen Fehler. Es wird kein Haftnotizbeitrag im Vordergrund beworben, wenn dieser Haftnotizbeitrag nicht auf der aktuellen Seite vorhanden ist.

Ein System, das die .sticky CSS-Klasse auf die sticky Posts setzt, wäre auch Nice.

1
mll