Nhận tất cả các danh mục và bài viết trong các thể loại


7

Tôi đang tìm kiếm một giải pháp cho phép tôi in như sau:

Cat 1        Cat 2        Cat 3
 Post 1       Post 1       Post 1
 Post 2       Post 2       Post 2
 Post 3                    Post 3
                           Post 4

BIÊN TẬP

Tôi đang tìm kiếm một cái gì đó sẽ chỉ yêu cầu một truy vấn cơ sở dữ liệu! Vì vậy, nếu bạn có foreachmã trong đó theo new WP_Querysau thì đó không phải là thứ tôi đang tìm kiếm (tôi đang dự định đưa mã này lên trang chủ của trang web của tôi).


bị hạ thấp khi yêu cầu của bạn biến điều này từ một câu hỏi WordPress thành một vấn đề sắp xếp php.
Michael

3
Xin vui lòng xem câu trả lời của tôi. Vô cùng nhanh chóng và hiệu quả. Xem số liệu thống kê tôi đã thêm trong câu trả lời của mình
Pieter Goosen

Làm thế nào về điều này? <? php $ erer = wp_list_clists ('orderby = name & title_li = & show_count = 1'); var_dump ($ erer); ?> Bạn có thể nhận được cách sử dụng HTML và css sau đó.
Vishwa

Câu trả lời:


16

EDIT REVISIT SỐ 2

Tôi chưa bao giờ chạm vào API thoáng qua , cho đến hôm nay khi tôi thấy câu trả lời @MikeSchinkel trong bài đăng này . Điều này truyền cảm hứng cho tôi để xem lại bài đăng này một lần nữa. Sau một số thử nghiệm, tôi đã đưa ra những điều sau đây:

  • Thời gian thực hiện đã giảm từ ~ 0,07 giây xuống ~ 0,002 giây

  • Thời gian truy vấn cơ sở dữ liệu đã giảm khoảng một nửa

  • Với tạm thời, chỉ có 2 truy vấn db được thực thi

Cách mã hoạt động (Chỉ cần thảo luận về các thay đổi từ mã gốc từ REVISIT ):

BƯỚC 1

Chúng ta cần lưu giá trị của $qtạm thời, đây là giá trị giữ danh sách danh mục với tiêu đề bài.

BƯỚC 2

Trước tiên chúng ta cần kiểm tra xem có tồn tại tạm thời không và nếu không tồn tại, hãy tạo tạm thời. Nếu tạm thời tồn tại, lấy thông tin của nó

BƯỚC 3

Thông tin này hiện được truyền qua một foreachvòng lặp để in danh sách với tên danh mục và tiêu đề bài.

BƯỚC 4

Khi nó đứng, thoáng qua sẽ được cập nhật cứ sau mười hai giờ. Điều này có thể được thiết lập để phù hợp với nhu cầu của bạn. Tuy nhiên, thoáng qua sẽ cần phải được xóa và tạo lại mỗi khi trạng thái của bài đăng thay đổi. Đây có thể là từ bản nháp để xuất bản, một bài đăng mới được xuất bản hoặc một bài đăng đang bị vùi dập. Để làm điều này, bạn cần sử dụng delete_transientcái sẽ được nối với transition_post_statuscái sẽ được kích hoạt mỗi khi trạng thái của bài đăng thay đổi

Đây là mã hoàn chỉnh:

Trong hàm của bạn.php

add_action( 'transition_post_status', 'publish_new_post', 10, 3 );

function publish_new_post() {
   delete_transient( 'category_list' );
}

Trong mẫu của bạn, nơi bạn cần hiển thị danh sách của bạn

<?php
if ( false === ( $q = get_transient( 'category_list' ) ) ) {

    $args = array( 
        'posts_per_page' => -1
    );

    $query = new WP_Query($args); 

    $q = array();

    while ( $query->have_posts() ) { 

        $query->the_post(); 

        $a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>';

        $categories = get_the_category();

        foreach ( $categories as $key=>$category ) {

            $b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>';    

        }

        $q[$b][] = $a; // Create an array with the category names and post titles
    }


    /* Restore original Post Data */
    wp_reset_postdata();

set_transient( 'category_list', $q, 12 * HOUR_IN_SECONDS );
}

foreach ($q as $key=>$values) {
        echo $key;

        echo '<ul>';
            foreach ($values as $value){
                echo '<li>' . $value . '</li>';
            }
        echo '</ul>';
    }


?>

CÁCH MẠNG

Gần đây tôi đã đưa ra một giải pháp rất nhẹ nhanh hơn nhiều so với các giải pháp khả thi khác được đưa ra. Trên trang web thử nghiệm của tôi, tôi nhận được tổng thời gian tạo chỉ ~ 0,07 giây và chỉ có 6 truy vấn db theo Trình theo dõi truy vấn trong khi các phương thức khác cho tôi thời gian tạo ~ 0,35 giây và thêm 50 truy vấn db.

Đây là một sự cố về phương pháp của tôi

BƯỚC 1

Trước tiên bạn cần tạo một truy vấn tùy chỉnh WP_Queryđể truy xuất tất cả các bài đăng được xuất bản

$args = array( 
        'posts_per_page' => -1
    );

    $query = new WP_Query($args);   
    $q = array();

    while ( $query->have_posts() ) { 

    }

    /* Restore original Post Data */
    wp_reset_postdata();

Bước 2

Sử dụng get_the_category, lấy danh sách tất cả các danh mục mà bài đăng thuộc về.

$categories = get_the_category();

        foreach ( $categories as $key=>$category ) {

            $b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>';    

        }

BƯỚC 3

Gán các biến cho tiêu đề bài viết và các thể loại của bài viết

$a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>';

$b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>';    

BƯỚC 4

Kết hợp hai biến này để tạo thành một mảng nhiều chiều

$q[$b][] = $a;

Để xem những gì đang xảy ra trong mảng, chỉ cần làm một var_dump

?><pre><?php var_dump($q); ?></pre><?php

BƯỚC 5

Sử dụng foreachcác vòng lặp, tạo danh sách bài đăng của bạn được sắp xếp theo thể loại

foreach ($q as $key=>$values) {
    echo $key;

    echo '<ul>';
        foreach ($values as $value){
            echo '<li>' . $value . '</li>';
        }
    echo '</ul>';
}

TẤT CẢ MỌI THỨ NGAY BÂY GIỜ!

Đây là mã hoàn chỉnh

<?php

    $args = array( 
        'posts_per_page' => -1
    );

    $query = new WP_Query($args);   
    $q = array();

    while ( $query->have_posts() ) { 

        $query->the_post(); 

        $a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>';

        $categories = get_the_category();

        foreach ( $categories as $key=>$category ) {

            $b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>';    

        }

        $q[$b][] = $a; // Create an array with the category names and post titles
    }

    /* Restore original Post Data */
    wp_reset_postdata();

    foreach ($q as $key=>$values) {
        echo $key;

        echo '<ul>';
            foreach ($values as $value){
                echo '<li>' . $value . '</li>';
            }
        echo '</ul>';
    }

?>

2
Tại sao các danh mục khác được nhân đôi?
winresh24

Làm thế nào tôi có thể làm điều đó với loại bài tùy chỉnh?
winresh24

@ Pieter-Goosen Mã tuyệt vời! Thay vì sử dụng <ul>, tôi muốn sử dụng một mẫu từ một tệp. Tôi đã thử bao gồm tệp trong `foreach ($ value là $ value) {include (template.php);} nhưng sau đó nó đặt tên bài đăng làm tiêu đề trang, thay vì tiêu đề bài đăng. Bất cứ ý tưởng làm thế nào tôi có thể khắc phục điều này?
harvey

1

Tôi chỉ muốn thêm giải pháp của tôi bắt nguồn từ câu hỏi này. Điều này lưu trữ truy vấn cho các danh mục và cũng lưu trữ các bài đăng, bao gồm cả nội dung bài đăng, trong mỗi thể loại. Lần đầu tiên bộ đệm được lấp đầy có các truy vấn cơ sở dữ liệu bình thường, tuy nhiên một khi đã điền vào các danh mục và bài đăng được lưu trong bộ nhớ cache, do đó không có thêm truy vấn cơ sở dữ liệu.

// Transients API all categories and all posts
$query_categories = get_transient('cached_categories');
if ( false === $query_categories){
    $args_cat = array(
        // order by category name ascending
        'orderby' => 'name',
        'order' => 'ASC',
        // get only top level categories
        'parent' => 0
    );
    // Instead of caching a WP Query I cache 'get_categories()'.
    $query_categories = get_categories($args_cat);
    // var_dump($query_categories);
    set_transient('cached_categories', $query_categories, DAY_IN_SECONDS );
}

// Full posts query
// if there are categories filled with posts
if (!empty ($query_categories) && !is_wp_error( $query_categories )) {

    foreach ($query_categories as $category) {

        // var_dump($category);
        $query_category_posts = get_transient('cached_posts_' . $category->slug );
        if ( false === $query_category_posts ){

            // Query all posts by slug inside each category
            $args_category_posts = array(
                'post_type' => 'post',
                // The category slug and category name we get from the foreach over all categories
                'category_name' => $category->slug
            );

            // Here I cache the WP_Query, though this runs for all categories.
            // Because of that the '$category->slug' is used to serve a string and not an object.
            $query_category_posts = new WP_Query($args_category_posts);         
            set_transient( 'cached_posts_' . $category->slug , $query_category_posts, DAY_IN_SECONDS );
        }

        if ($query_category_posts->have_posts()) {
            while ($query_category_posts->have_posts()) {
                $query_category_posts->the_post(); ?>
                <article class="<?php echo $category->slug ?>-article">
                    <h2 class="<?php echo $category->slug ?>-article-title">
                        <a href="<?php echo get_permalink() ?>"><?php echo get_the_title() ?></a>
                    </h2>
                    <p class="<?php echo $category->slug ?>-post-info">
                        <?php the_time('d. m. Y') ?>
                    </p>
                    <div <?php post_class() ?> >
                        <?php the_content(); ?>
                    </div>
                </article> <?php
            }
        } // end loop
    } // end foreach
wp_reset_postdata() ;
} // end if there are categories filled with posts

0

thử ngay mã này

$cat_ids=array();
foreach (get_categories() as $cat)
{
    array_push($cat_ids, $cat->cat_ID);
}
$the_query = new WP_Query(array('post_type'=>'post', array('category__and' => $cat_ids) ) );
if( $the_query->have_posts() ): 
    while ( $the_query->have_posts() ) : $the_query->the_post(); 
        echo the_title();
    endwhile;
endif; 
wp_reset_query();

0

Đây là giải pháp của tôi để có được các danh mục và bài viết trong các danh mục đó như là một kết quả.

Ví dụ của tôi dựa trên danh mục phân loại document_categorybài tùy chỉnh và loại bài tùy chỉnh documents. Nhưng tôi chắc chắn bạn sẽ có được ý tưởng.

$result = [];

$categories = get_terms( [
    'taxonomy' => 'document_category'
] );

foreach ( $categories as $index => $category ) {
    $args      = [
        'post_type'      => 'documents',
        'posts_per_page' => - 1,
        'public'         => true,
        'tax_query'      => [
            [
                'taxonomy'         => 'document_category',
                'field'            => 'term_id',
                'terms'            => $category->term_id,
                'include_children' => true
            ]
        ]
    ];
    $documents = get_posts( $args );

    $result[ $index ]['category']  = $category;
    $result[ $index ]['documents'] = $documents;
}

return $result;

-1

Tôi đã xây dựng một cái gì đó cho tôi rằng tôi sử dụng khá nhiều, đây là mã, bạn có thể sử dụng sên, id hoặc đối tượng hạn trong $categoriesmảng, nếu bạn muốn lấy tất cả các danh mục bạn có thể sử dụng get_terms()và cung cấp với một loạt đối tượng hạn, nhưng hãy cẩn thận, không có điều trị cho phân cấp trên mã này.

$categories = array( 1, 'slug', 3 );
echo '<ul>';
foreach($categories as $category) {
    $term = ( is_numeric($category) || is_object($category) ? get_term( $category, 'category' ) : get_term_by( 'slug', $category, 'category' ) );
    $args = array(
        'cat' => $term->term_id
        // Add any other arguments to fit your needs
    );
    $q = new WP_Query( $args );
    if( $q->have_posts() ) {
        echo '<li><a href="' . get_term_link( $term->term_id, 'category' ) . '">' . $term->name . '</a><ul>';
        while( $q->have_posts() ) {
            $q->the_post();
            echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
        }
        echo '</ul></li>';
    } else {

    }
}
echo '</ul>';

O (n2) không hiệu quả
S ..

-1

Chưa được thử nghiệm, nhưng một trong những cách tiếp cận đơn giản nhất tôi sẽ thử là:

<?php
    $category_ids = get_all_category_ids();
    foreach ($category_ids as $values) {
        $args = array('category' => $value);
        $posts_array = get_posts( $args );
        foreach ($posts_array as $post) : setup_postdata($post);
?> 
    <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php
        endforeach;
        wp_reset_query();
    }
?>

Vấn đề tương tự như mã của Sagive
Ben

đồng ý. Không có cách nào để có được một truy vấn duy nhất được thực hiện. Tải bất kỳ trang nào cho Wordpress có nhiều truy vấn, trước khi thêm mã tùy chỉnh. Tất cả các truy vấn tích hợp sử dụng lớp WPDB. Cách duy nhất để thực hiện nó trong một truy vấn duy nhất là với sql giao dịch của riêng bạn hoặc bằng cách biến WPDB thành một lớp cha cho một lớp khác cho mục đích này và gọi nó theo cách đó.
Neil Davidson

Thông báo get_all_category_ids();hiện đã bị khấu hao
Pieter Goosen

O (n) không hiệu quả
S ..

-1

Bạn có thể sử dụng ... Đặt số lượng bài đăng bạn cần ...

Ngoài ra tôi đã đặt tất cả bên trong một div, vì vậy bạn có thể thực hiện cấu trúc và thiết kế mà bạn đang tìm kiếm.

<?php  
    $allcats = get_categories('child_of=0'); 

    foreach ($allcats as $cat) :
        $args = array(
            'posts_per_page' => 3, // set number of post per category here
            'category__in' => array($cat->term_id)
        );

        $customInCatQuery = new WP_Query($args);

        if ($customInCatQuery->have_posts()) :
            echo '<div>';
            echo '<h3>'.$cat->name.'</h3>';
            echo '<ul>';
            while ($customInCatQuery->have_posts()) : $customInCatQuery->the_post(); ?>

            <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
        <?php
            endwhile; 
            echo '</ul></div>'; 
        ?>

<?php
        else :
            echo 'No post published in:'.$cat->name;                
        endif; 
        wp_reset_query();
    endforeach; 
?>

Hi vọng điêu nay co ich.


1
Thx, nhưng lấy ví dụ về nói 10 loại. Trong trường hợp đó, mã của bạn gây ra 11 truy vấn SQL. Tôi đang tìm kiếm 1 truy vấn SQL. Điều tốt nhất có lẽ là nhận được tất cả các bài đăng, được sắp xếp theo danh mục, nhưng tôi không biết làm thế nào để làm điều đó (tôi không tìm thấy order_by = cattrong codex)!?
Ben

Tôi không nghĩ nó có vấn đề một chút nếu 10 danh mục hoặc 20 ... (đã thử với 20) trừ khi bạn đang cố tải một số lượng lớn bài đăng mà trong mọi trường hợp có thể làm chậm tải trang .. hãy thử - bạn sẽ tìm thấy nó thực sự dễ chịu - cố gắng sắp xếp lại sau khi được tải qua các danh mục có nghĩa là xây dựng một mã lớn và hầu như vô dụng (theo ý kiến ​​khiêm tốn của tôi :))
SEO Sagive

1
Không, không cần, bạn chỉ cần thay đổi đầu ra một chút (ví dụ: danh sách kết thúc cho cat n và danh sách bắt đầu cho cat n + 1) mỗi khi bài đăng có một danh mục khác với danh mục của bài trước ... Rất nhiều đơn giản hơn là bắn phá cơ sở dữ liệu nghèo nàn của bạn với hơn 20 truy vấn trên mỗi trang tải ... (theo ý kiến ​​khiêm tốn của tôi :)
Ben

Tôi nghĩ rằng chúng tôi sẽ hỏi cơ sở dữ liệu cùng một câu hỏi nhưng chỉ yêu cầu các công cụ khác nhau ở đầu ra .. tôi không thấy sự khác biệt ... bên cạnh đó - đó là một truy vấn logic .. "hãy cho tôi * đầu tiên từ danh mục này" .. . cho tôi đầu tiên * từ danh mục đó "thay vì đưa cho tôi bài đăng đó, một lần nữa, một lần nữa .. nó cũng giống như vậy nhưng tôi đang đập dữ liệu theo cách tôi cần ... trừ khi tôi nhầm ..
SEO Sagive

1
Sự khác biệt là số lượng truy vấn db. Một lớn so với nhiều nhỏ ...;)
Ben

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.