I would like some help to post all the posts of my website into a blogroll sorted by categories and subcategories.
The end-result HTML I would like to see displayed would be something like this:
<div id="content">
<div id="category1">
<ul id="posts">
<li>post1</li>
<li>post2</li>
<li>post3</li>
</ul><!-- #posts -->
</div><!-- #category1 -->
<div id="category2">
<div id="sub-category1">
<ul id="posts">
<li>post4</li>
<li>post5</li>
<li>post6</li>
</ul><!-- #posts -->
</div><!-- #sub-category1 -->
<div id="sub-category2">
<ul id="posts">
<li>post7</li>
<li>post8</li>
<li>post9</li>
</ul><!-- #posts -->
</div><!-- #sub-category2 -->
</div><!-- #category2 -->
</div><!-- #content -->
The file-structure I foresaw for this would be something like this:
custom-category.php
//this file would pull out the categories, sort them and create the container divs for #category and #sub-category and call the post info from within it's loop/query with get_template_part( 'content', get_post_format() );
content.php
//this file would sort the ul#posts and all sorts of info I might want to add regarding the post itself
Now the main issues I have right now, is not really knowing where to start looking to even try and figure this out by myself. I keep looking at the default category.php
file and I feel it'll look nothing like it.
I've tried looking at plugins but some only sort the categories in side-bars, others allow creating custom fields for categories but reviews mention you can't call on those values. I've tried the wp_list_categories(); function to try and start somewhere, but it doesn't even list the sub-categories.
I've read about creating your own query_posts();
or get_posts();
but I don't really know where to start with those.
Since this isn't really a single question, I'd like to try and point the questions out for clarity, but feel free to add other info you might feel would take care of the issue, cause I might ask the wrong questions xD
1- How do I start "the Loop" to obtain the categories/sub-categories?
2- How do I sort the categories and keep the sub-categories nested?
3- How will I make sure the posts will fall into the right divs? Just in case WP does something funny.
Thank you for the help.
--- Update ---
I've been poking the internet trying to find solutions and I'm starting to get somewhere, but not quite there yet. This is what I've got so far:
<?php
// get all the categories from the database
$args1 = array(
'orderby' => 'ID',
'order' => 'ASC',
'hierarchical' => true,
);
$cats = get_categories( $args1 );
// loop through the categries
foreach ($cats as $cat) {
// setup the cateogory ID
$cat_id= $cat->term_id;
// Make a header for the cateogry
echo "<h2>".$cat->name."</h2><p>".$cat->term_id."</p>";
// create a custom wordpress query
$args2 = 'cat=' . $cat_id . '&orderby=date&order=DESC&post_per_page=-1';
query_posts( $args2 );
// start the wordpress loop!
if (have_posts()) : while (have_posts()) : the_post(); ?>
<?php // create our link now that the post is setup ?>
<a href="<?php the_permalink();?>"><?php the_title(); ?></a>
<?php echo '<hr/>'; ?>
<?php endwhile; endif; // done our wordpress loop. Will start again for each category ?>
<?php } // done the foreach statement ?>
I found this piece of code on this website. It outputs all the categories and puts the posts under them, but it replicates the posts for the parent category like this:
<h2>Category1</h2><p>2</p>
<a href="http://localhost/wordpress/2013/05/06/test0/">test0</a>
<hr>
<h2>Category2</h2><p>3</p>
<a href="http://localhost/wordpress/2013/05/15/test2/">test2</a>
<hr>
<a href="http://localhost/wordpress/2013/05/14/test1/">test1</a>
<hr>
<h2>Sub-category1</h2><p>4</p>
<a href="http://localhost/wordpress/2013/05/14/test1/">test1</a>
<hr>
<h2>Sub-category2</h2><p>5</p>
<a href="http://localhost/wordpress/2013/05/15/test2/">test2</a>
<hr>
As you can see the posts, test1 and test2 are displayed in Category2 and that isn't quite what I wanted, as described in the initial question (end-result HTML).
I believe I need to add a conditional statement to verify if the current category has children and if it does jump to the child categories, if not populate it. But I'm still trying to figure out how to do that. I haven't reached a point where I'm comfortable enough to start trying to implement the div's that I intend to have in the end-result HTML but I have a feeling I'll have an issue with that as well. At this point I'm basically trying to learn a bit more about this "loop stuff" till I get a decent result that will allow me to wrap my head around the whole thing.
I am aware of these 2 links A and B but I'm still a novice and can't really get there quite yet, so I'm basically working with code I see is working and will try to get it improved as I move along.
--- Update ---
This seems to output the posts in the correct order and without repeating themselves for parent categories.
<?php
// get all the categories from the database
$args1 = array(
'orderby' => 'ID',
'order' => 'ASC',
'hierarchical' => true
);
$cats = get_categories( $args1 );
// loop through the categries
foreach ($cats as $cat) {
$cat_id= $cat->term_id;// setup the cateogory ID
$cat_name= $cat->name;// setup the category name
$parent= $cat->category_parent;// setup the category parent
$cat_child= get_term_children( $cat_id, 'category' ); //the function I had get_category_children(); was deprecated... fixed that
$has_child=bool; //
if( empty($cat_child)) { $has_child= false; }
else { $has_child= true; }
if ( $parent == 0 && $has_child == true ) { //is parent && has child -> post title
echo "<h2>".$cat_name."</h2>";
echo '<hr/>'; }
elseif ( $parent == 0 && $has_child == false ) { //is parent && no child -> loop posts
echo "<h2>".$cat_name."</h2>";
// create a custom wordpress query
$args2 = 'cat=' . $cat_id . '&orderby=date&order=DESC&post_per_page=-1';
query_posts( $args2 );
// start the wordpress loop!
if (have_posts()) : while (have_posts()) : the_post(); ?>
<?php the_title(); ?>
<?php echo '<hr/>'; ?>
<?php endwhile; endif; }
else { //is child -> loop posts
echo "<h2>".$cat_name."</h2>";
// create a custom wordpress query
$args2 = 'cat=' . $cat_id . '&orderby=date&order=DESC&post_per_page=-1';
query_posts( $args2 );
// start the wordpress loop!
if (have_posts()) : while (have_posts()) : the_post(); ?>
<?php the_title(); ?>
<?php echo '<hr/>'; ?>
<?php endwhile; endif; // done our wordpress loop. Will start again for each category ?>
<?php }} // done the foreach statement ?>
I divided this into 3 conditions: is parent and has child
, is parent but no child
and is child
. The function that allowed me to get here is get_category_children();
.
Reading the code now makes me think I could've just checked if $cat_child
was empty directly in the main if/elseif statements, avoiding the $has_child
run-a-round.