Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I am looking for a solution that allows me to print the following:

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

EDIT: I am looking for something that will only require one database query! So if you have a foreach in your code followed by a new WP_Query then that is not what I am looking for (I am planing to put this onto my website's homepage).

share|improve this question
    
downvoted as your requirement turns this from a WordPress question into a php sorting problem. –  Michael Feb 25 '12 at 11:29
add comment

5 Answers 5

There is no way you are going to achieve this in one query as far as I know. Your demands have made you blind to other possible solutions if I can make this statement in this fashion.

There is one thing that you always have to keep in mind, a very valuable scale that you need to take in consideration when making database queries. That is, the amount of queries vs the actual time taken to execute these queries. Remeber, light weight functions can execute 20 or 30 queries faster than one heavy weight function.

Although you explicitly stated:

I am looking for something that will only require one database query! So if you have a foreach in your code followed by a new WP_Query then that is not what I am looking for

I'm going to give you a solution that works, runs a few queries but is not heavy weight and on that basis it should suite your needs perfectly

This can be done using WP_Query and get_categories. See my code for a detailed description of what every piece of code is doing

<?php
$categories = get_categories(); //retrieve all the categories and save them as a variable $categories

    foreach($categories as $category) : // Use foreach to split $categories into individual categories and store as variable $category
?>
    <p><?php // Display the category name as a link to the actual category ?>
        Category: <a href="<?php get_category_link( $category->term_id )?>" title="<?php sprintf( __( "View all posts in %s" ), $category->name ) ?>"><?php echo $category->name ?></a> 
    </p>


<?php
    $catid = $category->cat_ID; //Store the category ID as a variable to be used in WP_Query

    $args = array( 
        'cat' => $catid,
    );

    $query = new WP_Query($args);   

    // Start the Loop. You can use your own loop here
        while ( $query->have_posts() ) : $query->the_post(); 
    ?>  
        <p> 
            <?php the_title( '<a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a>' ); //Display only the title of the posts in the category ?> 
        </p>
    <?php
        endwhile;
    endforeach;
/* Restore original Post Data */
wp_reset_postdata();
?>

EDIT

There are another solution with get_posts which actually runs less db queries

$categories = get_categories(); //retrieve all the categories and save them as a variable $categories

    foreach($categories as $category) : // Use foreach to split $categories into individual categories and store as variable $category
?>
    <p><?php // Display the category name as a link to the actual category ?>
        Category: <a href="<?php get_category_link( $category->term_id )?>" title="<?php sprintf( __( "View all posts in %s" ), $category->name ) ?>"><?php echo $category->name ?></a> 
    </p>

    <p><?php // Display the category description ?>
        Description: <?php echo $category->description ?>
    </p>

<?php
    $catid = $category->cat_ID; //Store the category ID as a variable to be used in get_posts

    $args = array( 
        'cat' => $catid,
    );

    $query = get_posts($args);  

    // Start the Loop. You can use your own loop here
        foreach ( $query as $post ) : setup_postdata( $post ); ?>
            <li>
                <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
            </li>
<?php 
        endforeach; 

    wp_reset_postdata();

    endforeach;
share|improve this answer
add comment

if you are looking for a plugin, List Category Posts might work for you.

Fore a query, take a look at:

share|improve this answer
    
    
Thx, but that doesn't help. –  Ben Feb 24 '12 at 22:09
add comment

I've build something for me that I use quite alot, here is the code, you can use slugs, ids or the term object in the $categories array, if you want to get all the categories you can use get_terms(), and feed with a bunch of term objects, but be careful, there is no treatment for hierarchy on this code.

$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>';
share|improve this answer
add comment

Untested, yet one of the simplest approaches I would try is the following:

<?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();
    }
?>
share|improve this answer
    
Same problem as Sagive's code –  Ben Feb 24 '12 at 23:13
    
ok. There is no way to get a single query done. Loading any page for Wordpress has multiple queries as it is, before adding custom code. All built-in queries use the WPDB class. The only way to do it in a single query is with your own transact sql or by making WPDB a parent class to another class for this purpose and calling it that way. –  Neil Davidson Mar 4 '12 at 0:14
add comment

You can use this... Set the amount of posts you need...

Also I have put it all inside a div, so you can do the structure and design your looking for.

<?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; 
?>

Hope this helps. Cheers, Sagive

share|improve this answer
    
Thx, but take the example of say 10 categories. In that case your code causes 11 SQL queries. I am looking for 1 SQL query. The best thing would probably be to get all posts, ordered by category, but I don't know how to do that (I didn't find order_by = cat in the codex) !? –  Ben Feb 24 '12 at 23:12
    
i dont think it matters one bit if its 10 categories or 20... (tried it with 20) unless you are trying to load a huge number posts which in any case might slow the page load.. try it - you'll find it real breezy - trying to rearrange after loaded via categories would mean building a huge and mostly useless code (to my humble opinion :) ) –  Sagive SEO Feb 24 '12 at 23:33
    
No it doesn't, you just need to change the output slightly (i.e. end list for cat n, and start list for cat n+1) everytime a post has a category that is different from the previous post's category... A lot simpler than bombarding your poor database with 20+ queries per pageload... (to my humble opinion :) –  Ben Feb 25 '12 at 0:04
    
i think it would we asking the database the same question but just ordering stuff differently on the output end.. i dont see the difference... besides - its a logical query.. "give me the first * from this category"... give me the first * from that category" instead of give me that post, again, again, again.. its the same way but i am puling the data in the way i need it... unless i am mistaken.. –  Sagive SEO Feb 25 '12 at 0:37
    
The difference is the number of db queries. One big vs. many small... ;) –  Ben Feb 25 '12 at 1:11
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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