0

I've asked this question already on the WordPress forum, but it sank like a stone, which isn't at all unusual.

I've set up a general Articles page with multiple loops, in order to display the first three articles from any category within the custom post type "Articles." These are all hard-coded into the template, like the one below, changing only the category ID number:

<?php
  $args = array(
  'cat' => 13,
  'posts_per_page' => 3,
  'post_type' => Article
  );
  query_posts( $args );

  if( have_posts() ):?>

..and so on. What follows is all the necessary code to produce the title, the permalink, the excerpt, etc.

The loops work fine. The problem is that they're hard-coded into the template, which would require that with every new category added, I add a loop to the template file. I need to find a solution so that instead, every time a new category is created it automatically gets added as a block to the Articles page. Also, I need to have it create a link, just as though I were using wp_get_archives, so that each category block links to its own page which contains ALL of the posts within that category (with pagination, if necessary).

I can't think of any function which accomplishes this. Has anyone ever come across this problem before? Or does this require some heavy custom PHP coding that WordPress doesn't support unless hacked?

4
  • I'd strongly advise against the use of query_posts, it should never be used. Instead use WP_Query, which works very similarly, or the pre_get_posts filter
    – Tom J Nowell
    Commented May 26, 2013 at 0:15
  • I keep hearing this, but nobody explains it. Why shouldn't I? It does what I want it to do.
    – 1db
    Commented May 26, 2013 at 1:48
  • You may think that, I did myself once, but it actually goes one step further and does more, and can muddle things up. The main loop is a WP_Query object, query_posts discards that object and creates a new one, essentially doubling the page load cost. It's impossible to nest loops using query_posts, and it's a destructive API to call, and it's not a clean call. With WP_Query it's obvious which query you're in, and if you need to modify the query args of a page load, use the pre_get_posts filter
    – Tom J Nowell
    Commented May 26, 2013 at 13:36
  • Here is a breakdown on the use of query_posts() wordpress.stackexchange.com/questions/1753/… Commented Jun 1, 2013 at 8:30

2 Answers 2

2

You get all categories with:

$categories = get_categories( array ( 'fields' => 'ids' ) );

This returns an array with all categories.

Then you should use get_posts() or a new WP_Query, because query_posts() has many side-effects and should not be used anymore.

Sample code, as illustration:

$categories = get_categories( array ( 'number' => 5 ) );
print '<pre>$categories = ' . htmlspecialchars( var_export( $categories, TRUE ), ENT_QUOTES, 'utf-8', FALSE ) . '</pre>';

$boxes = array();

foreach ( $categories as $category )
{
    $boxes[ $category->term_taxonomy_id ]['posts'] = get_posts(
        array(
            'numberposts'    => 5,
            'category'       => $category->term_taxonomy_id,
            'posts_per_page' => 3,
            'post_type'      => 'post'
        )
    );
    $boxes[ $category->term_taxonomy_id ]['title'] = $category->category_nicename;
}

foreach ( $boxes as $cat_id => $box )
{
    printf(
        '<h2><a href="%1$s">%2$s</a></h2>',
        get_category_link( $cat_id ),
        $box['title']
    );

    print '<ul>';

    foreach ( $box['posts'] as $post )
        printf(
            '<li><a href="%1$s">%2$s</a></li>',
            get_permalink( $post->ID ),
            esc_html( $post->post_title )
        );

    print '</ul>';
}
2

This is actually quite easy to do! First, use get_categories to get a list of all your categories. Next, loop over these categories and get posts within those categories like you're doing above.

As a side note, you should avoid using query_posts for multiple loops. Check out this page which covers the topic in great detail.

Sample Code

$categories = get_categories();
foreach ( $categories as $category ) :
    $category_query = new WP_Query( array(
        'cat' => $category->term_id,
        'posts_per_page' => 3,
        'post_type' => 'Article'
    ) );

    while ( $category_query->have_posts() ) : $category_query->the_post();

        # Your existing code...

    endwhile;
    wp_reset_postdata();
endforeach;

Within the foreach loop, you can get a link to the category with get_category_link()

2
  • I think I should have made it plain before: I'm not a programmer, my grasp of PHP is rudimentary (like, I can recognize it), and my understanding of WordPress isn't any better (for instance, that page you linked to doesn't make any sense to me whatsoever). Is there any real-world example somewhere that I can look at? I'm not asking anyone to write my code for me...but sometimes codex pages (or other tutorials) have exactly what you need.
    – 1db
    Commented May 25, 2013 at 23:37
  • I added some sample code for you to help get you started. Commented May 26, 2013 at 0:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.