web-dev-qa-db-ja.com

最初の文字または番号で投稿をグループ化する方法

Can You plz guide me  タイトルの最初の文字か数字のどちらかでそれらの投稿をソート可能にするロジックをどのように作成するか?

「手紙」をクリックすると投稿が与えられた最初の文字で更新される必要があります「手紙」をクリックすると投稿が与えられた最初の文字で更新される必要があります

あなたがオリジナルのページをチェックしたいなら: https://neverquit.000webhostapp.com/library

3
Ashley

もっと良いアプローチがあると思います。英数字の用語を保持するカスタムの分類法を作成してから、各投稿に正しい用語を割り当てます。

投稿の保存アクションを使用して、投稿の保存時に投稿を正しい用語に自動的に割り当てることができます。

function save_index( $post_id ) {
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return;
    }

    $slug   = 'post';
    $letter = '';

    // only run for posts
    if ( isset( $_POST['post_type'] ) && ( $slug != $_POST['post_type'] ) ) {
        return;
    }

    // Check user capabilities
    if ( ! current_user_can( 'edit_post', $post_id ) ) {
        return;
    }

    $taxonomy = 'index'; // our custom taxonomy

    if ( isset( $_POST['post_type'] ) ) {

        // Get the title of the post
        $title = strtolower( $_POST['post_title'] );

        // The next few lines remove A, An, or The from the start of the title
        $splitTitle    = explode( ' ', $title );
        $blacklist     = [ 'an ', 'a ', 'the ' ];
        $splitTitle[0] = str_replace( $blacklist, '', strtolower( $splitTitle[0] ) );
        $title         = implode( ' ', $splitTitle );

        // Get the first letter of the title
        $letter = substr( $title, 0, 1 );

        // Set to 0-9 if it's a number
        if ( is_numeric( $letter ) ) {
            $letter = '0-9';
        }

    // set term as first letter of post title, lower case
    wp_set_post_terms( $post_id, $letter, $taxonomy );
    }
}

add_action( 'save_post', 'save_index' );
5
Alex Sancho

これは少し短くて詳細ではありません。ある時点でもっと詳細にこれに戻る予定です。

しかし、短期的には、このソリューションは必要なことをすべて実行するはずです。明らかにそれを拡張する必要がありますが、それは基本です。

この例では、投稿タイプがmbe-membersで、投稿タイプの書き換えスラグが/member/であると仮定しています。

手順1)カスタム書き換えルールとクエリ変数を追加する

add_action( 'init', function () {

    add_rewrite_tag( '%member-filter%', 'members/filter/([a-zA-Z0-9-]{1,3})', 'post_type=mbe-members&filter=' );
    add_permastruct( 'member-filter', '%member-filter%', array( 'with_front' => false ) );

} );

あなたの投稿タイプが登録される前にこれが実行されることを確認する必要があります。

また、書き換え規則を確実に消去する必要があります。

注: 今のところ非常に簡単にするために、残りのタスクはPost Type Archiveテーマ・テンプレート・ファイルで完了します。 (私は将来的にこの部分を良くするでしょう)

ステップ2)何をフィルタリングする必要があるかを決定する

$filter       = get_query_var( 'filter' );
$filter_start = null;
$filter_end   = null;

if ( strpos( $filter, '-' ) !== false ) {

    if ( $pieces = explode( '-', $filter ) ) {

        if ( isset( $pieces[0] ) ) {
            $filter_start = $pieces[0];
        }

        if ( isset( $pieces[1] ) ) {
            $filter_end = $pieces[1];
        }

    }

} else {
    $filter_start = substr( $filter, 0, 1 );
}

このフィルタリングは、文字や数字の範囲も許可します。

A/K/A - /members/filter/aまたは/members/filter/a-z/を指定できます

ステップ3)フィルタリングされた一致の投稿IDを問い合わせる

global $wpdb;

$post_ids = array();

if ( ! is_null( $filter_start ) && ! is_null( $filter_end ) ) {

    $range = range( $filter_start, $filter_end );

    foreach ( $range as $value ) {

        $query_args = array(
            'SELECT' => 'ID',
            'FROM'   => $wpdb->posts,
            'WHERE'  => 'post_title'
        );

        if ( $query = $wpdb->get_results( $wpdb->prepare( "
            SELECT {$query_args['SELECT']}
            FROM {$query_args['FROM']}
            WHERE {$query_args['WHERE']}
            LIKE %s
            AND post_type = %s
            ", "{$value}%", 'mbe-members' ) ) ) {

            foreach ( $query as $result ) {

                if ( ! in_array( $result->ID, $post_ids ) ) {
                    $post_ids[] = $result->ID;
                }

            }

        }

    }

} else {

    if ( ! is_null( $filter_start ) ) {

        $value = $filter_start;

        $query_args = array(
            'SELECT' => 'ID',
            'FROM'   => $wpdb->posts,
            'WHERE'  => 'post_title',
        );

        if ( is_numeric( $value ) ) {
            $query_args['LIKE'] = '%d';
        } else {
            $query_args['LIKE'] = '%s';
        }

        if ( $query = $wpdb->get_results( $wpdb->prepare( "
            SELECT {$query_args['SELECT']}
            FROM {$query_args['FROM']}
            WHERE {$query_args['WHERE']}
            LIKE {$query_args['LIKE']}
            AND post_type = %s
            ", "{$value}%", "mbe-members" ) ) ) {

            foreach ( $query as $result ) {

                if ( ! in_array( $result->ID, $post_ids ) ) {
                    $post_ids[] = $result->ID;
                }

            }

        }

    }

}

ステップ4)投稿オブジェクトを照会して表示を出力する

$content = '';

if ( ! empty( $post_ids ) ) {

    $query = new \WP_Query( array(
        'post_type'              => 'mbe-members',
        'posts_per_page'         => absint( get_option( 'posts_per_page' ) ),
        'post_status'            => 'publish',
        'orderby'                => 'post_title',
        'order'                  => 'ASC',
        'update_post_meta_cache' => false,
        'update_post_term_cache' => false,
        'suppress_filters'       => true,
        'post__in'               => $post_ids
    ) );

    if ( $query->have_posts() ) {

        foreach ( $query->posts as $post ) {
            $content .= $post->post_title . '<br />';
        }

    }

}

echo '<div>' . PHP_EOL;

echo '<ul class="nav nav-tabs" role="tablist">' . PHP_EOL;

$class = '';

if ( $filter == '0-9' ) {
    $class = 'active';
}

echo '<li role="presentation" class="' . $class . '"><a href="' . site_url( '/member/filter/0-9/' ) . '" aria-controls="0-9" role="tab">0-9</a></li>' . PHP_EOL;

foreach ( range( 'a', 'z' ) as $letter ) {

    $class = '';

    if ( $letter == $filter_start ) {
        $class = 'active';
    }

    echo '<li role="presentation" class="' . $class . '"><a href="' . site_url( '/member/filter/' . $letter . '/' ) . '" aria-controls="' . $letter . '" role="tab">' . $letter . '</a></li>' . PHP_EOL;

}

echo '</ul>' . PHP_EOL;

echo '<div class="tab-content">' . PHP_EOL;

$class = '';

if ( $filter == '0-9' ) {
    $class = 'active';
}

echo '<div role="tabpanel" class="tab-pane ' . $class . '" id="0-9">' . PHP_EOL;

if ( $filter == '0-9' ) {
    echo $content;
}

echo '</div>' . PHP_EOL;

foreach ( range( 'a', 'z' ) as $letter ) {

    $class = '';

    if ( $letter == $filter_start ) {
        $class = 'active';
    }

    echo '<div role="tabpanel" class="tab-pane ' . $class . '" id="' . $letter . '">' . PHP_EOL;

    if ( $letter == $filter_start ) {
        echo $content;
    }

    echo '</div>' . PHP_EOL;

}

echo '</div>' . PHP_EOL;

echo '</div>' . PHP_EOL;

結論

私が言ったように、これは非常に素早い答えでした。これは確かにあなたの質問に答えます。それは非常に粗くて単純ですが、それはあなたが必要とすることをします。私はもう少しエレガントな解決策になるようにこの答えを改良しようと思います。

1
Michael Ecklund