I created a sidebar for the dynamic WordPress category pages.
Example Url: https://example.com/category/firstcategory/secondcategory/othercategories/
SEO Silo:
Info about SEO Silos: What is a content silo and how does it benefit for SEO?
An imaginary company offers books, films and toys. And so the following categories are usually formed:
Company category:
* company
** books
** movies
** games
They have subcategories.
* company
** books
*** drama
*** comedy
** movies
*** drama
*** comedy
*** romance
** games
*** actions
*** for kids
*** click and point
The subcategories in turn have entries.
If I now come to the books category, only everything about books may appear in the category tree and not movies and games as well. Ideally not even the upper category, like that:
* company
** books
*** drama
---- drama Book1
---- drama Book2
If I’m in the drama category for books, I dont want to see the others like comedy in the books category too.
If I’m in the Company category, its okay to see the first subcategories like:
* company
** books
** movies
** games
If I’m in the books category:
* company
** books
*** drama
*** comedy
Problem:
The code isn’t optimized yet, because I’m just trying out a lot.
Active Category level 2 already works (apart from the indentation).
- When calling up the second category, sometimes not all (existing) sub-categories appear.
- Probably the smallest problem is that the categories are not indented as a list.
// Manual: https://stackoverflow.com/questions/9225920/how-to-check-which-level-category-it-is-for-wordpress
function get_the_level($id, $type = 'category') {
return count(get_ancestors($id, $type));
}
function children_sidebar_shortcode($atts) {
global $post;
if (!is_category()) {
return false;
}
$returnval = "";
$category = get_queried_object();
$category_id = $category->term_id;
$n = 0;
$item_cat_level = 0;
// Active Category is level 2 and more
if (get_the_level($category_id) >= 2) {
$returnval .= "<h2>Active Category is level 2 and more</h2>";
$args = array(
'type' => 'post',
'child_of' => 0,
'parent' => '',
'orderby' => 'term_group', //'name',
'order' => 'ASC',
'hide_empty' => 0,
'hierarchical' => 1,
'exclude' => '',
'include' => '',
'number' => '',
'taxonomy' => 'category',
'pad_counts' => false
);
} else {
$returnval .= "<h2>Active Category is level 1 or less</h2>";
$args = array(
'type' => 'post',
'child_of' => $category_id,
'parent' => '', // set here same category as you want to fetch only their 1st level category on in depth child
'orderby' => 'term_group', //'name',
'order' => 'ASC',
'hide_empty' => 0,
'hierarchical' => 1,
'exclude' => '',
'include' => '',
'number' => '',
'taxonomy' => 'category',
'pad_counts' => false
);
}
$categories = get_categories($args);
if (count($categories) > 0) {
// show the category description
//$returnval .= category_description();
$returnval .= "<ul>";
foreach ($categories as $category) {
$item_cat_level = get_the_level($category->term_id);
// Active Category is level 2 and more
if (get_the_level($category_id) >= 2) {
if (
// Category is part of the parent Categories/Terms
cat_is_ancestor_of($category->term_id, $category_id)
// SubLevel Category 2
|| $item_cat_level >= 2
// Active Category (same)
|| $category->term_id === $category_id
) {
$category_link = sprintf(
'<a href="%1$s" alt="%2$s">%3$s</a>',
esc_url(get_category_link($category->term_id)),
esc_attr($category->name),
esc_html($category->name)
);
$returnval .= sprintf("<li class='cat-item cat-item-%d %s'>%s", $category_id, ($category->term_id === $category_id) ? 'current-cat-ancestor' : '', $category_link);
}
} else {
if (
// Category is part of the parent Categories/Terms
//cat_is_ancestor_of($category->term_id, $category_id)
// SubLevel Category 2
//||
$item_cat_level <= 1
// Active Category (same)
//|| $category->term_id === $category_id
) {
$category_link = sprintf(
'<a href="%1$s" alt="%2$s">%3$s</a>',
esc_url(get_category_link($category->term_id)),
esc_attr($category->name),
esc_html($category->name)
);
$returnval .= sprintf("<li class='cat-item cat-item-%d %s'>%s", $category_id, ($category->term_id === $category_id) ? 'current-cat-ancestor' : '', $category_link);
}
}
}
$returnval .= "</ul>";
}
// Attributes
$atts = shortcode_atts(
array(
'name' => '',
),
$atts,
''
);
return $returnval;
}
add_shortcode('children_sidebar', 'children_sidebar_shortcode');
2
Answers
The answer is only a temporary solution:
I tried indenting with the query for a level change. Until then set an optical (but not semantic) indentation by a margin-left-0 to 2. With classes ml-%d (0,1,2).
I didn't link the first two category levels where the output doesn't work yet, until the code optimization. With a direct call, a 301 (permanent) redirect, which is removed again when the code is optimized.
So looking at the edited question, I think what you are really looking for is, a category tree having only the (immediate) children or siblings of the current category (i.e. the queried object/term on a category archive page), right?
If so, then this should work for you:
Note regarding the shortcode parameters: I added
show_parent
, which if true or1
, then the immediate parent category will always be added to the output. So for example, on the Books category page, the shortcode would output something like this: (the "Books" is not a link)And BTW, using a custom function to manually generate the categories list (i.e. the
<li>
tags) will give you full control over the HTML markup, but just so that you know, you could also usewp_list_categories()
like so:Just replace the entire
foreach
above with this:Last but not least, you can style the current category/
<li>
using thecurrent-cat
class. 🙂