web-dev-qa-db-ja.com

タグを並べるがアルファベット順には並ばない

アルファベット順以外の方法で投稿にタグを配置する方法を見つけようとしています。たとえば、投稿には次のタグがあります。 alphabetacharlie。投稿は常にその順番でタグを整理します。

タグを投稿に表示する方法を制御したいです。アルファベット順ではなく、投稿に追加された順に投稿タグを並べたいのですが。例えば; alpha(entries2nd)、beta(entries1st)、charlie(entries3rd)が投稿に追加されますが、タグはこの順序で当然alpha, beta, charlieのようにリストされます。この順番で表示してもらいたいのですが。 beta, alpha, charlie

これは可能ですか?もしそうなら、あなたは私を指示してもらえますか?

6
Mr. B

そのための1つの方法は、編集時に現れる順番でタグを渡すアクションset_object_termsを使用して、タグの順番を投稿メタデータとして保存することです。例えば、 "functions.php"のように:

// Called in admin on updating terms - update our order meta.
add_action( 'set_object_terms', function ( $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids ) {
    if ( $taxonomy != 'post_tag' ) {
        return;
    }
    // Save in comma-separated string format - may be useful for MySQL sorting via FIND_IN_SET().
    update_post_meta( $object_id, '_tt_ids_order', implode( ',', $tt_ids ) );
}, 10, 6 );

// Reorder terms using our order meta.
function wpse174453_get_the_terms( $terms, $post_id, $taxonomy ) {
    if ( $taxonomy != 'post_tag' || ! $terms ) {
        return $terms;
    }
    if ( $ids = get_post_meta( $post_id, '_tt_ids_order', true ) ) {
        $ret = $term_idxs = array();
        // Map term_ids to term_taxonomy_ids.
        foreach ( $terms as $term_id => $term ) {
            $term_idxs[$term->term_taxonomy_id] = $term_id;
        }
        // Order by term_taxonomy_ids order meta data.
        foreach ( explode( ',', $ids ) as $id ) {
            if ( isset( $term_idxs[$id] ) ) {
                $ret[] = $terms[$term_idxs[$id]];
                unset($term_idxs[$id]);
            }
        }
        // In case our meta data is lacking.
        foreach ( $term_idxs as $term_id ) {
            $ret[] = $terms[$term_id];
        }
        return $ret;
    }
    return $terms;
}

// Called in front-end via the_tags() or related variations of.
add_filter( 'get_the_terms', 'wpse174453_get_the_terms', 10, 3 );

// Called on admin edit.
add_filter( 'terms_to_edit', function ( $terms_to_edit, $taxonomy ) {
    global $post;
    if ( ! isset( $post->ID ) || $taxonomy != 'post_tag' || ! $terms_to_edit ) {
        return $terms_to_edit;
    }
    // Ignore passed in term names and use cache just added by terms_to_edit().
    if ( $terms = get_object_term_cache( $post->ID, $taxonomy ) ) {
        $terms = wpse174453_get_the_terms( $terms, $post->ID, $taxonomy );
        $term_names = array();
        foreach ( $terms as $term ) {
            $term_names[] = $term->name;
        }
        $terms_to_edit = esc_attr( join( ',', $term_names ) );
    }
    return $terms_to_edit;
}, 10, 2 );
4
bonger