web-dev-qa-db-ja.com

カスタム分類用語のリストをページ分割する方法

私は "books"という名前のカスタム分類法を作成し、SEを少し手助けしながらその内容を画像グリッドに表示することができましたが、以下のコードはその方法を示しています。

add_shortcode('taxography' , 'execute_taxography' );
function execute_taxography() {
    $wpbtags = get_terms( 'books' );
    $output.= '<div class="grid"><div class="taxography-grid"><ul>';
    foreach($wpbtags as $tag) {
        $output.= '<li class="item"><a href="'. get_term_link($tag->term_id, 'books' ) .'" style="background-image: url(\'http://localhost/wordpress/wp-content/uploads/books/' . $tag->slug . '.png\')"><span class="count">'. $tag->count .'</span><span class="taxography-name">'. $tag->name . '</span></a></li>';
    }
    $output.= '</ul></div></div>';
    return $output;
}

今、私はただ新しいページを作成して、短いコード[taxography]を入れるだけでうまくいきますが、私がやろうとしているのは、このページが特定の量の本だけを表示するようにページ付けを追加することです。私は この答え そして他の多くの人に従ったが、私はまだこの問題を解決できない!何か案は?

2
PavilionVI

あなたのショートコードは実行するのが非常に高価です。 get_term_link() 用語IDを指定してフィードすると、用語オブジェクトをクエリするためのdbクエリが発生するため、ユーザーフレンドリーではありません。あなたがget_term_link()にオブジェクトという用語を与えるならば、それは幸せであり、そしてオブジェクトという用語を得るためにどんな仕事もする必要はありません。

そのセクションをちょっと見てください

function get_term_link( $term, $taxonomy = '' ) {
    global $wp_rewrite;

    if ( !is_object($term) ) {
        if ( is_int( $term ) ) {
            $term = get_term( $term, $taxonomy );
        } else {
            $term = get_term_by( 'slug', $term, $taxonomy );
        }
    }

ご覧のとおり、$termがtermオブジェクトではなく、term IDまたはslugの場合、termオブジェクトを取得するために追加の呼び出しがdbに対して行われます。これは、100個の用語があり、その用語ページへのリンクを取得する必要があり、IDまたはスラッグのいずれかをget_term_link()に渡す場合、100個の追加のdb呼び出しを行うことになります。あなたはすでにオブジェクトという用語を持っているので、それを単にget_term_link()に与えれば、100 dbの呼び出しを節約できます。

ページネーションとそれをどのように機能させるかに関しては、あなたが持っている用語の数を知っている必要があるだけで、1ページに必要な用語の数でそれを割り、そしてページの最大量があるでしょう。また、1ページあたりの用語数に現在のページ番号を掛けた値となる用語オフセットを計算する必要があります。

1つだけ注意してください、あなたはURLをハードコードしたくないでしょう、あなたは動的な値を使いたいでしょう。アップロードディレクトリへのパスを返すために wp_upload_dir() を見てください、それであなたのショートコードでそれに応じてそれを変更することを忘れないでください

add_shortcode( 'taxography', function ( $atts )
{
    $attributes = shortcode_atts(
        [ 
            'terms_per_page' => 12,
            'taxonomy'      => 'books',
            // Add any attribute which you seem fit
        ],
        $atts,
        'taxography'
    );

    // Sanitize and validate our inputs and set variables
    $tpp = filter_var( $attributes['terms_per_page'], FILTER_VALIDATE_INT );
    $taxonomy = filter_var( $attributes['taxonomy'], FILTER_SANITIZE_STRING );

    // Make sure our taxonomy exists to avoid unnecessary work
    if ( !taxonomy_exists( $taxonomy ) )
        return false;

    // Our taxonomy exists, lets continue
    // Get the term count to calculate pagination.
    $term_count = get_terms( $taxonomy, ['fields' => 'count'] );

    // Check if we have terms to avoid bugs
    if ( !$term_count )
         return false;

    // We have terms, now calculate pagination
    $max_num_pages = ceil( $term_count / $tpp );
    // Get current page number. Take static front pages into account as well
    if ( get_query_var( 'paged' ) {
        $paged = get_query_var( 'paged' );
    } elseif ( get_query_var( 'page' ) {
        $paged = get_query_var( 'page' );
    } else {
        $paged = 1;
    }
    // Calculate term offset
    $offset = ( ( $paged - 1 ) * $tpp );

    // We can now get our terms and paginate it
    $args = [
        'number' => $tpp, // Amount of terms to return
        'offset' => $offset // The amount to offset the list by for pagination
    ];
    // Set our variable to hold our string
    $output = '';
    $wpbtags = get_terms( $taxonomy, $args );
    $output.= '<div class="grid"><div class="taxography-grid"><ul>';
    foreach($wpbtags as $tag) {
        $output.= '<li class="item"><a href="'. get_term_link($tag, $taxonomy ) .'" style="background-image: url(\'http://localhost/wordpress/wp-content/uploads/books/' . $tag->slug . '.png\')"><span class="count">'. $tag->count .'</span><span class="taxography-name">'. $tag->name . '</span></a></li>';
    }
    $output.= '</ul></div></div>';

    // Add our pagination links, I have used the default 'get_*_posts_link()'. Adjust accordingly
    $output .= get_next_posts_link( 'Next Terms', $max_num_pages ) . '</br>';
    $output .= get_previous_posts_link( 'Previous Terms' ) . '</br>';

    return $output;
});

ショートコードを正しく作成する方法とその使用方法については、ショートコードAPIもチェックすることをお勧めします。

編集

番号付けされたページネーションリンクのために、あなたは私が書いた修正版の私のページネーション機能を使うことができます ここで答えに 。コードをどのように使用すべきか、そしてどのように機能するのかについての私の答えをチェックしてください。

これはあなたのようなコードだけでなくあらゆる種類のクエリを扱うための修正版です。説明されているように関数を使うことができるはずですが、唯一の変更はqueryに整数値を渡すことができることです。これは最大ページ数になります。

/**
 * @author Pieter Goosen
 * @license GPLv2 
 * @link http://www.gnu.org/licenses/gpl-2.0.html
 *
 * This function returns numbered pagination links or text pagination links
 * depending what is been set
 *
 * Paginated numbered links uses get_pagenum_link() to return links to the
 * required pages
 * @uses http://wpseek.com/function/get_pagenum_link/
 *
 * The pagination links uses next_posts_link() and previous_posts_link()
 * @uses http://codex.wordpress.org/Function_Reference/next_posts_link
 * @uses http://codex.wordpress.org/Template_Tags/previous_posts_link
 *
 * @param array $args An array of key => value arguments. Defaults below 
 * - string query variable                  'query'                 => $GLOBALS['wp_query'],
 * - string Previous page text              'previous_page_text'    => __( '&laquo;' ),
 * - string Next page text                  'next_page_text'        => __( '&raquo;' ),
 * - string First page link text            'first_page_text'       => __( 'First' ),
 * - string Last page link text             'last_page_text'        => __( 'Last' ),
 * - string Older posts text                'next_link_text'        => __( 'Older Entries' ),
 * - string Newer posts text                'previous_link_text'    => __( 'Newer Entries' ),
 * - bool Whether to use links              'show_posts_links'      => false,
 * - int Amount of numbered links to show   'range'                 => 5,
 *
 * @return string $paginated_text
*/ 
function get_paginated_numbers( $args = [] ) {

    //Set defaults to use
    $defaults = [
        'query'                 => $GLOBALS['wp_query'],
        'previous_page_text'    => __( '&laquo;' ),
        'next_page_text'        => __( '&raquo;' ),
        'first_page_text'       => __( 'First' ),
        'last_page_text'        => __( 'Last' ),
        'next_link_text'        => __( 'Older Entries' ),
        'previous_link_text'    => __( 'Newer Entries' ),
        'show_posts_links'      => false,
        'range'                 => 5,
    ];

    // Merge default arguments with user set arguments
    $args = wp_parse_args( $args, $defaults );

    /**
     * Get current page if query is paginated and more than one page exists
     * The first page is set to 1
     * 
     * Static front pages is included
     *
     * @see WP_Query pagination parameter 'paged'
     * @link http://codex.wordpress.org/Class_Reference/WP_Query#Pagination_Parameters
     *
    */ 
    if ( get_query_var('paged') ) { 

        $current_page = get_query_var('paged'); 

    }elseif ( get_query_var('page') ) { 

        $current_page = get_query_var('page'); 

    }else{ 

        $current_page = 1; 

    }

    // Get the amount of pages from the query
    $max_pages = ( is_object( $args['query'] ) ) ? (int) $args['query']->max_num_pages : (int) $args['query'];

    /**
     * If $args['show_posts_links'] is set to false, numbered paginated links are returned
     * If $args['show_posts_links'] is set to true, pagination links are returned
    */
    if( false === $args['show_posts_links'] ) {

        // Don't display links if only one page exists
        if( 1 === $max_pages ) {

            $paginated_text = '';

        }else{

            /**
             * For multi-paged queries, we need to set the variable ranges which will be used to check
             * the current page against and according to that set the correct output for the paginated numbers
            */
            $mid_range      = (int) floor( $args['range'] / 2 );
            $start_range    = range( 1 , $mid_range );
            $end_range      = range( ( $max_pages - $mid_range +1 ) , $max_pages );
            $exclude        = array_merge( $start_range, $end_range );  

            /**
             * The amount of pages must now be checked against $args['range']. If the total amount of pages
             * is less than $args['range'], the numbered links must be returned as is
             *
             * If the total amount of pages is more than $args['range'], then we need to calculate the offset
             * to just return the amount of page numbers specified in $args['range']. This defaults to 5, so at any
             * given instance, there will be 5 page numbers displayed
            */
            $check_range    = ( $args['range'] > $max_pages )   ? true : false;

            if( true === $check_range ) {

                $range_numbers = range( 1, $max_pages );

            }elseif( false === $check_range ) {

                if( !in_array( $current_page, $exclude ) ) {

                    $range_numbers = range( ( $current_page - $mid_range ), ( $current_page + $mid_range ) );

                }elseif( in_array( $current_page, $start_range ) && ( $current_page - $mid_range ) <= 0 ) {

                    $range_numbers = range( 1, $args['range'] );

                }elseif(  in_array( $current_page, $end_range ) && ( $current_page + $mid_range ) >= $max_pages ) {

                    $range_numbers = range( ( $max_pages - $args['range'] +1 ), $max_pages );

                }

            }

            /**
             * The page numbers are set into an array through this foreach loop. The current page, or active page
             * gets the class 'current' assigned to it. All the other pages get the class 'inactive' assigned to it
            */
            foreach ( $range_numbers as $v ) {

                if ( $v == $current_page ) { 

                    $page_numbers[] = '<span class="current">' . $v . '</span>';

                }else{

                    $page_numbers[] = '<a href="' . get_pagenum_link( $v ) . '" class="inactive">' . $v . '</a>';

                }

            }

            /** 
            * All the texts are set here and when they should be displayed which will link back to:
             * - $previous_page The previous page from the current active page
             * - $next_page The next page from the current active page
             * - $first_page Links back to page number 1
             * - $last_page Links to the last page
            */
            $previous_page  = ( $current_page !== 1 )                       ? '<a href="' . get_pagenum_link( $current_page - 1 ) . '">' . $args['previous_page_text'] . '</a>' : '';
            $next_page      = ( $current_page !== $max_pages )              ? '<a href="' . get_pagenum_link( $current_page + 1 ) . '">' . $args['next_page_text'] . '</a>'     : '';
            $first_page     = ( !in_array( 1, $range_numbers ) )            ? '<a href="' . get_pagenum_link( 1 ) . '">' . $args['first_page_text'] . '</a>'                    : '';
            $last_page      = ( !in_array( $max_pages, $range_numbers ) )   ? '<a href="' . get_pagenum_link( $max_pages ) . '">' . $args['last_page_text'] . '</a>'            : '';

            /**
             * Text to display before the page numbers
             * This is set to the following structure:
             * - Page X of Y
            */
            $page_text      = '<span>' . sprintf( __( 'Page %s of %s' ), $current_page, $max_pages ) . '</span>';
            // Turn the array of page numbers into a string
            $numbers_string = implode( ' ', $page_numbers );

            // The final output of the function
            $paginated_text = '<div class="pagination">';
            $paginated_text .= $page_text . $first_page . $previous_page . $numbers_string . $next_page . $last_page;
            $paginated_text .= '</div>';

        }

    }elseif( true === $args['show_posts_links'] ) {

        /**
        * If $args['show_posts_links'] is set to true, only links to the previous and next pages are displayed
        * The $max_pages parameter is already set by the function to accommodate custom queries
        */
        $paginated_text = next_posts_link( '<div class="next-posts-link">' . $args['next_link_text'] . '</div>', $max_pages );
        $paginated_text .= previous_posts_link( '<div class="previous-posts-link">' . $args['previous_link_text'] . '</div>' );

    }

    // Finally return the output text from the function
    return $paginated_text;

}

あなたはそれをあなたのfunctions.phpまたはプラグインのどこにでも簡単に追加することができ、そしてあなたのショートコードの中で次のようにそれを呼び出すことができます

交換する

// Add our pagination links, I have used the default 'get_*_posts_link()'. Adjust accordingly
$output .= get_next_posts_link( 'Next Terms', $max_num_pages ) . '</br>';
$output .= get_previous_posts_link( 'Previous Terms' ) . '</br>';

if ( function_exists( 'get_paginated_numbers' ) )
    $output .= get_paginated_numbers( ['query' => $max_num_pages] );
3
Pieter Goosen