WordPress.org

Ready to get started?Download WordPress

Forums

Display by Category home.php template (52 posts)

  1. Kafkaesqui

    Posted 9 years ago #

    Along with my plugin work I've been spending a bit of time on template experiments, proof of concepts in organizing content differently in WordPress 1.5.

    A method that's requested often, and one that caught my interest, is to display recent posts organized within their respective categories, instead of just by date (descending). I've come up with one solution through a (very) modified post loop in a home.php template, and would like feedback on what I have so far, such as improvements to structure, streamlining code, etc.

    download template | view template | demo

    The modifications to The Loop I've made still only handle the last N posts, but it first retrieves the categories they've been posted to, and then organizes posts under each. By default categories are organized by latest post first, but uncomment the following line (remove the //) to sort/list the categories alphabetically:

    // uasort($cats, strcasecmp);

    I've commented throughout the template, but please ask if something isn't clear.

    Finally, the template is designed around the default (Kubrick) theme, so it'll work best with that; however the loop framework can be imported into any layout (with appropriate tweaking).

  2. Lorelle
    Member
    Posted 9 years ago #

    Oh, this is wonderful!!!! Something I've been wanting for ages.

    So this isn't a plugin but will be a change to the template files? Wow. Very awesome.

    Can you add more than one post to a couple of the demo categories so we can get a better feel for how more than one post would fit under a category?

    And would this display only the most recent posts on the index.php page, leaving out "archived" posts? So if WP is set to display 10 posts chronologically, it would now display 10 posts, chronologically but by category?

  3. Kafkaesqui

    Posted 9 years ago #

    "So this isn't a plugin but will be a change to the template files? "

    Correct. I looked at how one might incorporate it into a plugin, but got a little lost considering how to go about it. If it can, it would probably need to create a whole new query class to manage overriding The Loop, etc. That appears to be more work than what I put into the template.

    "Can you add more than one post to a couple of the demo categories so we can get a better feel for how more than one post would fit under a category?"

    Done.

    "And would this display only the most recent posts on the index.php page, leaving out "archived" posts?"

    That's right. So let's say you have a blog with 10 categories. If WordPress is set to display 10 posts per page, and the last 10 are in 6 categories, then only 6 categories with be displayed--with those last 10 posts organized chronologically under each of course. (It is also page-aware, so previous/next paging will continue to organize each page of posts in their group of categories.)

    A method could be constructed to display the last N posts for each category (or just select ones), but this would have to nix the built-in Loop functionality entirely.

  4. iand
    Member
    Posted 9 years ago #

    Excellent work and easy to integrate into existing styles. One question though - what is the criteria for chosing where a post with two cats goes? Does it go in to the first category listed, or both?

  5. Kafkaesqui

    Posted 9 years ago #

    If a post is in cats 1, 2 and 3, it will be displayed under the category 1 heading. So in other words, it ends up under the first category listed. I focused on 'posts in a single category' blogs because they seem to fit the bill for this template, but it wouldn't be difficult to modify the code so it displays posts under multiple categories.

    This sort of thing would be easier if only WordPress incorporated the concept of a 'primary' category...

  6. moshu
    Member
    Posted 9 years ago #

    So, could this work together with the Top Category plugin - as for 'primary'?
    http://wordpress.org/support/topic/34427

  7. Kafkaesqui

    Posted 9 years ago #

    moshu, taking a look at how the plugin works, I don't see why not. Right now my script compares the (first) category of a post with the 'current' category to determine the correct one to display it under. The code for that is:

    $category = get_the_category();
    if($current_cat == $category[0]->cat_ID) :

    Using Top Cat's topcat_get_the_main_category_id() function, this could be changed to:

    $category = topcat_get_the_main_category_id();
    if($current_cat == $category) :

    Or if one needed to test if the 'top' category has been set:

    $category = topcat_get_the_main_category_id();
    if(!$category) {
    $category = get_the_category();
    $category = $category[0]->cat_ID;
    }
    if($current_cat == $category) :

  8. moshu
    Member
    Posted 9 years ago #

    To quote my nephew: "kewl, maaan" :)
    My interest at this moment is pure theoretical, but I'll save this snippet for future use. Thanks!

  9. pmonaco
    Member
    Posted 9 years ago #

    Thank you for posting that script it was exactly what I was looking for. Is there way for me to exclude a category from being displayed? I tried a few thing but they didn't work. I'm not great at this php thing yet. Thanks again.

  10. Kafkaesqui

    Posted 9 years ago #

    (see next post)

    pmonaco,

    Near the beginning of the template find this block of code:

    /* collect categories */
          foreach($posts as $post) :
             $category = get_the_category();
             $cats[$category[0]->cat_ID] = $category[0]->cat_name;
             $cat_posts[$category[0]->cat_ID] = $post;
          endforeach;

    and replace it with this:

    /* collect categories */
          foreach($posts as $post) :
             $category = get_the_category();
             if(10 != $category[0]->cat_ID) {
                $cats[$category[0]->cat_ID] = $category[0]->cat_name;
                $cat_posts[$category[0]->cat_ID] = $post;
             }
          endforeach;

    Change 10 in

    if(10 != $category[0]->cat_ID) {

    to the category ID you want to pass over. If you need to exclude more than one category, just before the foreach line in the same block of code, insert this:

    $exclude_cats = array(1, 10, 20);

    Set the array to the category IDs you want to exclude, separating each with a comma. Then change the if line to:

    if(!in_array($category[0]->cat_ID, $exclude_cats)) {

  11. Kafkaesqui

    Posted 9 years ago #

    Actually, the code above will correctly exclude one or more categories, but at the disadvantage of not displaying the correct number of posts per page. I'll have to look at the template's code and see what can be done through query_posts or whatnot to solve this.

  12. Monika
    Member
    Posted 9 years ago #

    Kafkaesqui
    I've testes your code in the first post
    I'm using the custom query string plugin
    custom query string plugin

    it works!

    is_home show 5 posts per page, ordered by date DESC

    and if I have only 4 categories
    your code shows two posts of the first category

    if I have only 3 categories
    your code shows three posts of the first category

    if I have 5 categories
    your code shows one post per category

    if tested it with
    is_home show 15 posts per page, ordered by date DESC
    and so on

    :-)
    I'm happy

    and please take a look at this problem

    best regards
    Monika

  13. joelwalsh
    Member
    Posted 9 years ago #

    How would you go about removing the category title bar (with the link to the category page) from the posts for a particular category (i.e., your "main" category)?

    Also, how could you specify a maximum number of posts per individual categories...for instance, 5 max per the main category and one each for the rest.

  14. Kafkaesqui

    Posted 9 years ago #

    To selectively remove a category header, locate the <h2> that displays it (right after foreach($cats as $current_cat) in the template), and add just above it an if statement testing the category using a negation of the in_category() function:

    <?php if(!in_category(1)) : ?>

    Change 1 to the numeric category ID of your "main" category, and make sure to close up the if statement after the <h2> element:

    <?php endif; ?>

    "Also, how could you specify a maximum number of posts per individual categories"

    The "problem" I wanted to solve with this version of home.php was one of organizing the last N posts within their respective categories. For your second issue, you're asking to manage things far differently.

    Using query_posts(), you could create a custom loop displaying the last 5 posts only within your main category; then (using query_posts() again) initialize the "Display by Category" loop in my template to exclude the main category from the rest. However, this won't assure only a single post under each of the remaining categories. For that, you'd be better off passing up my template altogether and creating one that provides a custom loop for each category. This way you have full control over where a category is displayed, and how many posts appear in the home page under them.

    EDIT AFTER REPLIES:

    Beyond this, it is possible to set maximum posts displayed for each category. Just keep in mind if you want say 10 posts displayed on your main page, you can't then collect 10 through the normal loop process and set maximum values under a category. The reason for this is, if in the last 10 posts, 7 are in your main category, 2 in a second, and 1 in a third, you'll have only 7 posts showing (5 in main, and 1 for each of the other categories). If this is acceptable, a count could be set up that tracks the number of posts for each category, and stops displaying posts for a category once it hits its maximum.

  15. joelwalsh
    Member
    Posted 9 years ago #

    Thank you so much for your prompt reply. I'm partly just a little unsure if I'll want to have it your way, with only the most recent posts, regardless of category (better for regular visitors), or ensure there's at least one post from each (better for newbies).

    Would using a separate loop for each category slow down the page load or is the time the database takes to render things virtually inconsequental?

  16. joelwalsh
    Member
    Posted 9 years ago #

    Now that I've done that, it's only displaying posts from the "main" category. What's happened?

    <?php if(!in_category(1)) : ?><h2 id="cat-<?php echo $current_cat; ?>"><?php echo get_the_category_by_id($current_cat); ?></h2><?php endif; ?>

  17. Kafkaesqui

    Posted 9 years ago #

    When I change it to this:

    <?php if(!in_category(1)) : ?>
    <h2 style="text-align: center; background-color: #48b; margin: 0 -20px 0 -20px;" id="cat-<?php echo $current_cat; ?>"><a style="color: #fff;" href="<?php echo get_category_link($current_cat); ?>" title="View all posts in <?php echo get_the_category_by_id($current_cat); ?>"><?php echo get_the_category_by_id($current_cat); ?></a></h2>
    <?php endif; ?>

    It simply removes the category header. I don't see a problem with posts (other than the posts in my #1 cat seems a little lost without a category header to list them under).

  18. bawk
    Member
    Posted 8 years ago #

    I know this was designed to work with the kubrick template, but is it possible to display each catagory and its posts horizontally next to each other rather then vertically with the way that you have written your code ?

    Any help in making that happen would be hugely appreciated.

    Thanks

  19. nearlythere
    Member
    Posted 8 years ago #

    bawk, i'm not sure how you want the posts displayed, but a handy way to adapt the code to a new layout:

    run through the code, and replace any queries inside <? ?> with dummy text:

    <h2 style="text-align: center; background-color: #48b; margin: 0 -20px 0 -20px;" id="dummy"><a style="color: #fff;" href="dummylink" title="View all posts in dummy">dummy category</a></h2>

    so you can see it's only a header 2 tag.

    now, make the layout you do want to use, for example, have them all appear in on one line together, separated by |

    <a href="dummylink" title="View all posts in dummy">dummy category</a> |

    and replace the dummy text with the code you need:
    <a href="<?php echo get_category_link($current_cat); ?>" title="View all posts in <?php echo get_the_category_by_id($current_cat); ?>"><?php echo get_the_category_by_id($current_cat); ?></a> |

    if you want more complex CSS horizontal layouts for lists, see:
    http://www.alistapart.com/articles/taminglists/

  20. kvalvik
    Member
    Posted 8 years ago #

    Hi there! This looks interesting :-) But I need some help. Will it be possible to do something like this (copying from another topic)?

    I'm trying to adapt my front page, but since I don't know much php, I'm not having much luck with understanding the loop guides...

    I want to keep three articles from my main category over my two other categories which should be listed in a two columns view with five articles each.

    Here is a schematic look of what I want in the main content area of my front page:

    Main category | Sidebar
    Main category | Sidebar
    Main category | Sidebar
    Category2 | Category3 | Sidebar
    Category2 | Category3 | Sidebar
    Category2 | Category3 | Sidebar
    Category2 | Category3 | Sidebar
    Category2 | Category3 | Sidebar

  21. dermamo
    Member
    Posted 8 years ago #

    thanks for this great code. i have one question. does anybody know how i to create a layout with 3 columns near to each other?

  22. moshu
    Member
    Posted 8 years ago #

    Probably a lot people know, but that's a "design basics" question, not really a WP issue. I assume you'd have 3 different divs in the content area, or something like that.

  23. moshu
    Member
    Posted 8 years ago #

    kvalvik, it should be possible, but you really have to know well at least (x)html and css. And some basic php - to the extent to be able to read and copy/paste it.

  24. iamsof
    Member
    Posted 8 years ago #

    this is great.

    however, do you think it's possible to keep a category always on top and the other ones under that? so that the categories don't come up on the top whenever there's a new post added to it.

  25. moshu
    Member
    Posted 8 years ago #

    Did you take a look at the demo? - I mean before asking...

  26. iamsof
    Member
    Posted 8 years ago #

    i did. and i also installed it.

  27. moshu
    Member
    Posted 8 years ago #

    If you want one category always on the top - you probably need another solution.
    POssible the one explained to me in this thread:
    http://wordpress.org/support/topic/28203?replies=11#post-193667

  28. ScotStyle
    Member
    Posted 8 years ago #

    I did it thanks so much.

    http://artistsunite-ny.org/indexc.php

    One problem. I have set up three loops on the page with each one eliminating a few categories. the center loop should eliminate all categories but one (Feature Articles) but instead it shows 3 categories and I can't figure out why.

  29. webscreamer
    Member
    Posted 8 years ago #

    How do I install this plugin? What folder do I put it in?

    Sorry, I'm very very new to WordPress!

  30. moshu
    Member
    Posted 8 years ago #

    This is not a plugin. It is a template file that should go in the theme folder.
    Go back and read the OP (original post).

Topic Closed

This topic has been closed to new replies.

About this Topic

Tags