簡體   English   中英

按分類法對WordPress自定義帖子進行分組

[英]Grouping WordPress custom posts by taxonomy

我有一個名為“產品”的自定義帖子類型,它有兩個自定義分類 - “產品范圍”和“產品類別”。 該范圍用作頂級分組,而該類別是其中的子分組。

我已經設置了taxonomy-product-range.php模板,其中包含以下代碼:

<?php
$terms = get_terms('product-categories');
foreach( $terms as $term ):
?>     

<h2><?php echo $term->name;?></h2>
<ul>

    <?php                         
    $posts = get_posts(array(
        'post_type' => 'products',
        'taxonomy' => $term->taxonomy,
        'term' => $term->slug,
        'nopaging' => true
    ));
    foreach($posts as $post): setup_postdata($post);
    ?>

    <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>

    <?php endforeach; ?>

</ul>           

<?php endforeach; ?>

通過輸出產品並按產品類別對產品進行分組,這可以正常工作。 但是,它會輸出所有產品,無論您正在查看哪個存檔。 我需要它只輸出您正在查看的存檔的帖子。

這感覺就像它幾乎在那里,但我不知道如何解決它。

==編輯==

每個產品將屬於一個“范圍”和一個“類別”。 當人們訪問產品范圍存檔頁面時,我試圖顯示以下內容:

<h1>Range Title</h1>
<h2>Category 1 Title</h2>
<ul>
<li>Product 1 Title</li>
<li>Product 2 Title</li>
<li>Product 3 Title</li>
</ul>
<h2>Category 2 Title</h2>
<ul>
<li>Product 4 Title</li>
<li>Product 5 Title</li>
<li>Product 6 Title</li>
</ul>

簡單地刪除您擁有的代碼並將其替換為默認循環。 您不應該使用自定義查詢替換主查詢。 使用pre_get_posts根據需要更改主查詢。

這是您的分類頁面應該是什么樣子

if ( have_posts() ) {
    while ( have_posts() ) {
    the_post();

        // Your template tags and markup

    }
}

由於您的問題是排序,我們將使用usortthe_posts過濾器來解決這個問題,以便在循環運行之前進行排序,但是在主查詢運行之后。 我們不會使用多個循環,因為它們非常昂貴且資源密集,並且它會破壞頁面功能

我已經對代碼進行了評論,因此可以很容易地理解和理解。 注意: 以下代碼未經測試,由於陣列解除引用而需要PHP 5.4+

add_filter( 'the_posts', function ( $posts, $q ) 
{
    $taxonomy_page = 'product-range';
    $taxonomy_sort_by = 'product-categories'; 

    if (    $q->is_main_query() // Target only the main query
         && $q->is_tax( $taxonomy_page ) // Only target the product-range taxonomy term pages
    ) {
        /**
         * There is a bug in usort that will most probably never get fixed. In some instances
         * the following PHP warning is displayed 

         * usort(): Array was modified by the user comparison function
         * @see https://bugs.php.net/bug.php?id=50688

         * The only workaround is to suppress the error reporting
         * by using the @ sign before usort
         */      
        @usort( $posts, function ( $a, $b ) use ( $taxonomy_sort_by )
        {
            // Use term name for sorting
            $array_a = get_the_terms( $a->ID, $taxonomy_sort_by );
            $array_b = get_the_terms( $b->ID, $taxonomy_sort_by );

            // Add protection if posts don't have any terms, add them last in queue
            if ( empty( $array_a ) || is_wp_error( $array_a ) ) {
                $array_a = 'zzz'; // Make sure to add posts without terms last
            } else {
                $array_a = $array_a[0]->name;
            }

            // Add protection if posts don't have any terms, add them last in queue
            if ( empty( $array_b ) || is_wp_error( $array_b ) ) {
                $array_b = 'zzz'; // Make sure to add posts without terms last
            } else {
                $array_b = $array_b[0]->name;
            }

            /**
             * Sort by term name, if term name is the same sort by post date
             * You can adjust this to sort by post title or any other WP_Post property_exists
             */
            if ( $array_a != $array_b ) { 
                // Choose the one sorting order that fits your needs
                return strcasecmp( $array_a, $array_b ); // Sort term alphabetical ASC 
                //return strcasecmp( $array_b, $array_a ); // Sort term alphabetical DESC
            } else {
                return $a->post_date < $b->post_date; // Not sure about the comparitor, also try >
            }
        });
    }
    return $posts;
}, 10, 2 ); 

編輯

以下是您的循環在編輯中按順序顯示頁面的方式

if ( have_posts() ) {
    // Display the range term title
    echo '<h1>' . get_queried_object()->name . '</h1>';

    // Define the variable which will hold the term name
    $term_name_test = '';

    while ( have_posts() ) {
    the_post();

        global $post;
        // Get the terms attached to a post
        $terms = get_the_terms( $post->ID, 'product-categories' );
        //If we don't have terms, give it a custom name, else, use the first term name
        if ( empty( $terms ) || is_wp_error( $terms ) ) {
            $term_name = 'SOME CUSTOM NAME AS FALL BACK';
        } else { 
            $term_name = $terms[0]->name;
        }

        // Display term name only before the first post in the term. Test $term_name_test against $term_name
        if ( $term_name_test != $term_name ) {
            // Close our ul tags if $term_name_test != $term_name and if not the first post
            if ( $wp_query->current_post != 0 )
                echo '</ul>';

            echo '<h2>' . $term_name . '</h2>';

            // Open a new ul tag to enclose our list
            echo '<ul>';
        } // endif $term_name_test != $term_name

        $term_name_test = $term_name;

        echo '<li>' . get_the_title() . '</li>';    

        // Close the ul tag on the last post        
        if ( ( $wp_query->current_post + 1 ) == $wp_query->post_count ) 
            echo '</ul>';

    }
}

編輯2

上面的代碼現在已經過測試和運行。 根據要求,這是我本地安裝的測試運行。 對於這個測試,我使用了OP和我的代碼中的代碼。

結果

此結果是使用Query Monitor插件獲得的。此外,所有結果都包含由小部件,導航菜單,自定義函數等進行的相同額外查詢

  • OP中的代碼 - > 0.7940 s中的318 db查詢,頁面生成時間為1.1670s。 內存使用量為12.8Mb

  • 我的代碼回答 - > 0.1045秒內的46分貝查詢,頁面生成時間為0.1305秒。 內存使用量為12.6Mb

正如我之前所說,證據是在布丁中

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM