web-dev-qa-db-ja.com

カスタム項目のカスタム投稿タイプナビゲーション

カスタムフィールドでソートされたカスタム投稿タイプに取り組んでいます。投稿をリストしても問題ありません。しかし、これらのうちの1つについて単一の投稿ページに移動するときは、[前へ]および[次へ]ナビゲーションリンクを使用して、カスタムフィールドで指定されたソート順で前へ/次へ投稿します。デフォルトでは、WPは投稿日順に並べ替えます。

ソートリストのコード:

    // shortcodes
    // lor_list of letters: Lists all letters of reference in a table format
    add_shortcode('lor_list', 'aaaConsultant_shortcode_lor_list');

    function aaaConsultant_shortcode_lor_list() {
        global $wp_query;

        $oWP = new wp_query(array(
            'post_type' => 'letters_of_ref'
            , 'orderby' => 'meta_value'
            , 'meta_key' => 'aaaConsultant_dateofletter'
        ));

        $out = '<div id="lor_list_container">' . "\n";
        if (!$oWP->found_posts) {
            $out .= '<p>d\'Oh! We don\'t have any Letters of Reference yet.</p>' . "\n";
        } else {
            while ($oWP->have_posts()) {
                $oWP->the_post();
                $out .= '<a href="' . get_permalink() . '">' . get_the_title( $oWP->post->ID ) . '</a>' . "<br>\n";
            }
        }
        $out .= '</div> <!-- END #lor_list_container -->' . "\n";

        wp_reset_postdata();
        return $out;
    }

それ、どうやったら出来るの?

ご協力いただきありがとうございます。

1

前の投稿と次の投稿へのリンクを機能させるには、get_*_post_*フィルタにフックして、カスタムフィールドを使って実際に投稿をソートするようにクエリを修正する必要があります。以下のコードがうまくいくことを願っています。

前の投稿へのリンク

add_filter('get_previous_post_join', 'wpse96670_get_previous_post_join_custom_sort');
add_filter('get_previous_post_where', 'wpse96670_get_previous_post_where_custom_sort');
add_filter('get_previous_post_sort', 'wpse96670_get_previous_post_sort_custom_sort');
function wpse96670_get_previous_post_join_custom_sort($join) {
    global $wpdb;
    return "INNER JOIN {$wpdb->prefix}postmeta ON (p.ID = {$wpdb->prefix}postmeta.post_id)";
}
function wpse96670_get_previous_post_where_custom_sort($where) {
    global $wpdb, $post;
    $meta_value = get_post_meta($post->ID, 'aaaConsultant_dateofletter', true);
    return "WHERE 1=1  AND p.post_type = 'letters_of_ref' AND p.post_status = 'publish' AND {$wpdb->prefix}postmeta.meta_key = 'aaaConsultant_dateofletter' AND {$wpdb->prefix}postmeta.meta_value < '{$meta_value}'";
}
function wpse96670_get_previous_post_sort_custom_sort($sort) {
    global $wpdb;
    return "ORDER BY {$wpdb->prefix}postmeta.meta_value DESC LIMIT 1";
}

次の投稿へのリンク

add_filter('get_next_post_join', 'wpse96670_get_next_post_join_custom_sort');
add_filter('get_next_post_where', 'wpse96670_get_next_post_where_custom_sort');
add_filter('get_next_post_sort', 'wpse96670_get_next_post_sort_custom_sort');
function wpse96670_get_next_post_join_custom_sort($join) {
    global $wpdb;
    return "INNER JOIN {$wpdb->prefix}postmeta ON (p.ID = {$wpdb->prefix}postmeta.post_id)";
}
function wpse96670_get_next_post_where_custom_sort($where) {
    global $wpdb, $post;
    $meta_value = get_post_meta($post->ID, 'aaaConsultant_dateofletter', true);
    return "WHERE 1=1  AND p.post_type = 'letters_of_ref' AND p.post_status = 'publish' AND {$wpdb->prefix}postmeta.meta_key = 'aaaConsultant_dateofletter' AND {$wpdb->prefix}postmeta.meta_value > '{$meta_value}'";
}
function wpse96670_get_next_post_sort_custom_sort($sort) {
    global $wpdb;
    return "ORDER BY {$wpdb->prefix}postmeta.meta_value ASC LIMIT 1";
}

それならテンプレートにいくつかのコードが必要です。

    <?php 
        $oNext = get_adjacent_post(false, '', true);
        $oPrev = get_adjacent_post(false, '', false);

        if ($oPrev || $oNext) {
            echo '<div id="lor_nav">' . "\n";
        }
        if ($oPrev) {
            echo '<div class="prevlink"><a href="' . get_permalink($oPrev->ID) . '"> &laquo; ' . $oPrev->post_title . '</a></div>' . "\n";
        }
        if ($oNext) {
            echo '<div class="nextlink"><a href="' . get_permalink($oNext->ID) . '">' . $oNext->post_title . ' &raquo;</a></div>' . "\n";
        }
        if ($oPrev || $oNext) {
            echo '</div><div class="clear"></div>' . "\n";
        }
?>

説明が必要な場合はお知らせください。

3