web-dev-qa-db-ja.com

ホームページへのスティッキポスト、検索、タグ付け、アーカイブなしのプラグイン

今日質問があります。私は自分のウェブサイトでスティッキーポストを利用できるようにするための解決策を探しています。しかし、私はちょうどそれが以下のコードでホームページ上で動くようにしました。

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

付箋を検索、タグ、カテゴリにも表示することを考えていました。

何か解決策はありますか?ありがとうございます。

3
Jornes

これとまったく同じ質問が今週初め、または週末にかけて行われました。これが私が思い付いたアイデアです。

WP_Queryクラスの ソースコード を見ると、スティッキポストはホームページの最初のページにしか追加されていないことがわかります。必要に応じて必要なテンプレートを設定するためにこの動作を変更するためのフィルタも提供されていません。

ウィジェット、カスタムクエリ、ショートコード(do_shortcode()を使用する方が、関数自体を使用するより遅いため)や、表示する必要があるカスタム関数を使用して、他のテンプレートにスティッキポストを表示する方法はたくさんあります。私はthe_postsフィルターとpre_get_postsアクションを使うことにしました。

ここにあります:

  • get_option( 'sticky_posts' )でスティッキーな投稿として保存された投稿IDを取得する

  • pre_get_postsを使用して、メインのクエリからこの投稿を削除してください。付箋がホームページに含まれているので、私たちはホームページを除外します。通常のページも除外します

  • カスタム関数内で、投稿をスティッキー投稿として設定するためにget_postsを使用してカスタムクエリを実行します。

  • スティッキポストの返された配列をメインクエリの現在返されたポストとarray_mergeでマージします

  • このカスタム関数をthe_posts filterにフックします

コードは次のとおりです。(必須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

カテゴリページでのみ機能するようにするには、いくつかの変更(元のPietersの回答を参照)が必要でした。このソリューションは、現在のカテゴリ(および子カテゴリ)のすべてのスティッキーポストを表示しますが、検索、タグ、および単一ページには表示しません。

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

予想される404.phpではなくcategory.phpに向けられたという問題に遭遇したため、カテゴリが既存のカテゴリであるかどうかをチェックする機能を追加しました。 /existing-cat/not-existing-postのようなリンクは機能しましたが、/not-existing-post-or-page-or-catのようなリンクは機能しませんでした。

その投稿にCSSクラスが必要な場合は、このコードを投稿の内容を表示するテンプレートのPHP部分に追加します(例えば、20の場合はtemplate-parts/content.php)。

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

あなたが投稿post_class($stickyClass);のcssクラスにこのクラスを追加するより(この関数は、いくつかのクラスとあなたの追加されたクラスでHTML要素にclass属性を追加します)。この関数はすでに記事にあります。

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

Pieterの答えはうまくいきますが、フィルタリングされた投稿を表示したい場合(たとえば特定のカテゴリ)、allスティッキー投稿をページに表示します。

以下は私のために働きます。これをfunctions.phpに追加すると、フィルタリングされた投稿のサブセット内のスティッキのみが表示されます。

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

(クレジット: http://Pastebin.com/Y5jVrKg4を回避するために若干の変更を加えています。 9error)

しかし、大きな欠陥があります。このスティッキーポストが現在のページに表示されない場合は、スティッキポストが上に表示されません。

.sticky CSSクラスをスティッキーポストに設定するシステムもいいでしょう。

1
mll