Post Category

How to Display Only the Child Category in your WordPress Post Loop

Last updated on

by


One of the common questions people ask on WordPress forums is: ‘How do we display only the child category in WordPress post loop’?

In this post, we will answer that question with a possible solution. 

But before doing that, we will give you complete context into the problem so you can first understand the problem you are facing and then execute the solution. 

So without further ado, let’s dive into it. 

Attention: This guide is tailored for individuals who have a basic understanding of coding and are prepared to make edits directly to WordPress theme files. 

What is the WordPress Post Loop?

The WordPress post loop is a fundamental concept and structure within WordPress themes that allows the display of posts or pages on a website. 

If you have any programming knowledge, you must know about foreach, while, and for loops in programming. 

WordPress uses the same concept to display posts or pages on any page. 

It’s essentially a PHP code block that iterates through posts, fetching each one’s details so they can be displayed on the page. 

This loop is used on various types of pages within a WordPress site, including the homepage, category and tag archive pages, search results, and single post pages.

Core Components of the Post Loop

The WordPress post loop typically involves several key functions and statements that work together to fetch and display posts.

Start of the Loop: It begins with a conditional statement that checks if there are any posts to display by using have_posts() method. If there are posts available, the loop starts iterating over them.

if ( have_posts() ) :

 while ( have_posts() ) : the_post();

The Content: Inside the loop, WordPress provides functions to display or retrieve information about the current post in the iteration, such as the title, content, author, and date. Functions like the_title(), the_content(), the_author(), and the_date() are commonly used.

End of the Loop: The loop ends with an endwhile statement, followed by an endif statement to close the conditional check.

endwhile;

endif;

The loop is designed to display posts dynamically. Whether you’re viewing a page of recent blog posts, a category archive, or search results, the loop queries and presents the relevant posts based on the context of the page.

Beyond the main query generated by WordPress for each page, custom queries can be created using the WP_Query class. This allows for more specific or additional loops on a page, such as displaying posts from a certain category or with specific tags.

The loop is highly customizable. Theme developers can modify the loop in template files to create unique layouts, include custom fields, and integrate different post formats, enhancing the site’s design and user experience.

Now, that you have understood whats a WordPress post loop and how it functions, let’s take a look at the problem with displaying categories in a WordPress post loop. 

Displaying Categories in a WordPress Post Loop

In WordPress, each post can be assigned to one or more categories, which helps organize content into different topics or sections. 

Most themes use the function get_the_category_list() to display the categories associated with the post in the post content area. 

The problem is this function lacks built-in parameters for filtering categories by their hierarchy, such as only showing child categories or specifying the depth of categories to display.

This is the reason why by default, most WordPress themes are designed to show all assigned categories when a post is displayed within a loop. 

This includes both parent and child categories without distinction. 

For instance, if you have a blog post categorized under “Technology” (a parent category) and “Mobile Phones” (a child category of “Technology”), your WordPress theme will typically display both of these categories with the post. 

display only the child category

While the default behavior works well for many websites, several scenarios necessitate customization. 

Read: WordPress Full Site Editing Tutorial

If your site has a deep hierarchy of categories, displaying all related categories can clutter the post meta data area, making it visually overwhelming and detracting from the post’s title or content.

From a content strategy and SEO perspective too, emphasizing child categories might help in targeting more specific keywords and user intents. 

That’s when WordPress developers and website managers look for a way to customize the WordPress post loop so they can display only the child category or the parent category instead of displaying the entire category list. 

How to Customize the WordPress Post Loop to Display Only the Child Category?

Now, before you start editing any theme files to display only the child category, it’s important to take the following precautions: 

Access Your Website Files: You’ll need to either connect to your website using an FTP client or utilize your web hosting provider’s file manager. This access is critical for downloading, editing, or uploading theme files.

Backup Your Website: Before making any changes, it’s imperative to create a full backup of your website. This precaution ensures that, should any issues arise during your edits, you can restore your site to its previous state without losing data or functionality.

Use a Staging Environment: If available, perform your edits on a staging site rather than your live website. A staging site is a clone of your live site where you can test changes without impacting your actual website. This approach allows you to troubleshoot and refine your edits in a safe environment.

Use a Child Theme : If your edits involve theme files, consider using a child theme to preserve your changes against future theme updates. Edits made directly to a parent theme can be overwritten during an update, leading to the loss of your customizations.

Document Your Changes: Keep a record of the files and specific code snippets you modify. This documentation can be invaluable for future reference, troubleshooting, or if you need to revert changes.

By adhering to these guidelines, you can minimize risks and ensure a smoother process as you customize your WordPress site.

Remember, while editing theme files offers powerful customization options, it’s important to proceed with caution and due diligence to safeguard your website’s integrity and user experience.

With these basic precautions taken, let’s proceed to the next step. 

Look for the Right Theme File That Has the Category Related Code

To customize your WordPress theme so that you can display only the child category in WordPress loop, you first need to locate the theme file where this code is handled. 

This indeed requires some sleuthing, especially if you’re not familiar with the structure of your theme. 

However, with the right approach and tools, this task can be made simpler. 

Step 1: Choose a Suitable Code Editor

First, ensure you have a code editor that supports searching across files. Popular editors like Visual Studio Code, Sublime Text, and Atom offer robust search functionalities that can look through your entire theme directory.

Step 2: Access Your Theme Files

You’ll need to access your theme’s files. You can do this either by connecting to your website via FTP or by accessing your hosting file manager and navigating to your theme’s folder, typically located in wp-content/themes/your-theme-name.

Step 3: Use the Find Feature

Utilize the find feature of your code editor to search for specific functions that are related to category display. Here are some key functions and snippets you might look for:

  • the_category(): This tag displays the post categories.
  • get_the_category_list(): Retrieves the list of categories for a post.
  • has_category(): Checks if the current post has any of the given categories.
  • wp_list_categories(): Displays or retrieves a list of categories.

Once you’ve located the code, you can proceed to make your desired changes.

If you’re using a child theme, you’ll need to look for the right file in the parent theme. 

Once you have found the code that handles category list display in the parent theme, you can copy that file and paste it over in the child theme folder then make your changes in the copied file.

The structure within your child theme should mirror the parent theme’s structure. 

For instance, if the file was located in a subdirectory within the parent theme (e.g., parent-theme/page-templates/some-template.php), you should replicate this structure in your child theme by creating the same subdirectory (e.g., child-theme/page-templates/some-template.php).

Customize the WordPress Post Loop to Display Only The Child Category

While the exact code that will solve the problem will differ based on the theme you’re using, the algorithm that achieves this solution will be the same.

Hence, it’s important that you understand the algorithm so you can craft a solution around your theme.

Here’s how to filter the list of categories to display only the child category.

Like mentioned above, most themes use the function get_the_category() or other similar function to retrieve the list of categories associated with a post.

You need to write the logic for a filter applied to the list after its retrieved.

The filter will iterate over that list of categories and for each category, it will check if the current category has a parent category by examining its parent property. A parent value greater than 0 indicates it’s a child category (since top-level categories have a parent value of 0).

If the category is a child category, its ID (term_id) is added to an array.

After the loop ends, if the array of child categories is not empty, another loop is executed which builds out the formatted list of category links.

This loop uses get_category_link() to retrieve the URL to the category archive page, and get_cat_name() to get the category’s name.

An output string is built by concatenating the category names and links to build HTML links with <span> tags.

The output string is then echoed out.

With that said, let’s dive into 2 specific solutions – displaying only child categories in twentytwentyone classic theme and twentytwentyfour block theme.

How to Display Only the Child Category in Classic Themes

The following solution is suggested by WPBeginner for a theme like twentytwentyone. 

In Twenty Twenty-One theme, look for the template-tag file inside the inc folder. 

You’ll need to customize the following code that handles the display of categories. 

Here is the snippet responsible for displaying the categories:

if ( has_category() || has_tag() ) {
    echo '<div class="post-taxonomies">';
    $categories_list = get_the_category_list( wp_get_list_item_separator() );
    if ( $categories_list ) {
        printf(
            /* translators: %s: List of categories. */
            '<span class="cat-links">' . esc_html__( 'Categorized as %s', 'twentytwentyone' ) . ' </span>',
            $categories_list // phpcs:ignore WordPress.Security.EscapeOutput
        );
    }
    echo '</div>';
}

Now, you’ll need to replace the code between these lines: 

if ( has_category() || has_tag() ) {
    echo '<div class="post-taxonomies">';
// Replace the code in between these lines
}
    echo '</div>';
}

Here’s the code to replace it with:

// Get the IDs of categories
    $categories = get_the_category();
    $child_cat_ID = array(); // Array to store child category IDs
 
    foreach( $categories as $category ) {
        // Check if the category has a parent (i.e., it's a child category)
        if ( $category->parent > 0 ) {
            $child_cat_ID[] = $category->term_id; // Store the child category ID
        }
    }
 
    if ( !empty($child_cat_ID) ) {
        $output = '<span class="cat-links">' . esc_html__( 'Categorized as ', 'twentytwentyone' );
        foreach($child_cat_ID as $cat_id) {
            $cat_link = get_category_link($cat_id);
            $cat_name = get_cat_name($cat_id);
            $output .= '<a href="' . esc_url($cat_link) . '">' . esc_html($cat_name) . '</a>';
        }
        $output .= '</span>'; // Close the span tag after the loop
        echo $output; // Echo the entire output

This PHP code snippet is designed for use within a WordPress classic theme and aims to display links to all child categories of a post, formatted as HTML. It’s particularly useful for highlighting specific categorizations of content, excluding top-level parent categories for a cleaner presentation. Here’s a breakdown of how it operates.

How to Display Only the Child Category in Block Themes

Well, block themes have a different file structure and code architecture than classic themes.

Read this comparison about block themes vs classic themes in WordPress.

Let me explain how this list of categories is built in the twentytwentyfour block theme.

In the twentytwentyfour theme, the post-meta area that displays the list of categories along with other blog meta like author name and date is a template part.

In the post-meta template part, a block called post-terms handles the rendering and displaying of he category list associated with the post.

Hence, to display only the child category, we’ll need to edit the code in the post-terms.php file.

You’ll find this file in wp-includes/blocks directory.

In this scenario, we added some more complexity to the situation. We wanted to create a scenario where a post’s categories could include 1 or more parent categories along with their children as well as parent categories with no children.

So a post could be associated with these categories: ‘parent category’ and its child, ‘child 1’ as well as parent without child.

Since child 1 was more specific than its parent, we’ll include only the child category and not its parent. But since the other category ‘parent without child’ didn’t have a specific child tagged, we’ll keep the parent in the list.

display only the child category in block themes challenge

Here’s how we approached this:

Identify and Filter Categories: Initially, our function fetches all categories associated with the post. We then analyze these categories to determine their relationships—specifically, identifying which categories are parents and which are children. Using this relationship data, we apply a filtering logic: parent categories are excluded if their child categories are also listed; otherwise, they are included.

Manually Construct the Category List: Due to the limitations of the default get_the_term_list() function, which does not allow for custom filtering of terms based on their parent-child relationships, we implemented a manual construction of the category list. This approach involves creating individual link elements (<a>) for each category that meets our criteria and assembling these links into a cohesive HTML string.

To implement this solution, you need to insert 2 code snippets in the post-terms.php file in 2 different places.

The first snippet will be inserted immediately after the function get_the_terms(). So, when it retrieves the terms associated with a post ID, we will insert our custom filter to filter out based on parent-child relationship.

The second snippet will be inserted in place of the code that is building out the terms list. Look out for the function construction named get_the_terms_list() and replace that with our custom function that uses our filtered list to construct the list.

Here’s a detailed explanation on how to do that:

First, find the code between these two snippets in the post-terms.php file.

$post_terms = get_the_terms( $block->context['postId'], $attributes['term'] );
	if ( is_wp_error( $post_terms ) || empty( $post_terms ) ) {
		return '';
	}
//
//This is the code to replace
//
$classes = array( 'taxonomy-' . $attributes['term'] );
	if ( isset( $attributes['textAlign'] ) ) {
		$classes[] = 'has-text-align-' . $attributes['textAlign'];
	}
	if ( isset( $attributes['style']['elements']['link']['color']['text'] ) ) {
		$classes[] = 'has-link-color';
	}

Insert the below code snippet between these lines of code. This code filters the terms list and creates an array of filtered term IDs.

// Step 1: Identify child categories and their parents
    $parent_ids = [];
    foreach ($post_terms as $term) {
        if ($term->parent != 0) {
            $parent_ids[] = $term->parent;
        }
    }

    // Step 2: Filter categories
    $filtered_terms = array_filter($post_terms, function($term) use ($parent_ids) {
        // If it's a child category, include it
        if ($term->parent != 0) {
            return true;
        }
        // If it's a parent category but none of its children are in the list, include it
        return !in_array($term->term_id, $parent_ids);
    });

Now moving to the second part of the solution, which handles the construction of the term list.

Find the code between the following lines:

$suffix = '</div>';
	if ( isset( $attributes['suffix'] ) && $attributes['suffix'] ) {
		$suffix = '<span class="wp-block-post-terms__suffix">' . $attributes['suffix'] . '</span>' . $suffix;
	}

//Replace this code

**
 * Registers the `core/post-terms` block on the server.
 */
function register_block_core_post_terms() {
	$taxonomies = get_taxonomies(
		array(
			'publicly_queryable' => true,
			'show_in_rest'       => true,
		),
		'objects'
	);

Insert the following code between these lines. This code snippet takes the array of IDs that we created and constructs a list of category links to display.

// Manual construction of the term list using $filtered_terms
$links = array();
foreach ($filtered_terms as $term) {
    $link = get_term_link($term);
    if (is_wp_error($link)) {
        continue; // Skip if there's an error getting the term link
    }
    // Create the link HTML for each term
    $links[] = '<a href="' . esc_url($link) . '">' . esc_html($term->name) . '</a>';
}

// Join all the links with the separator
$terms_list = implode('<span class="wp-block-post-terms__separator">' . esc_html($separator) . '</span>', $links);

// Construct the full HTML with prefix, terms list, and suffix
$result = $prefix . $terms_list . $suffix;

// Return the constructed term list
return $result;
}

This is the result of our test.

display only the child category

Let us know in the comments if you found this helpful!