
Hello everyone. This page is an English translation of a Japanese page.
(The original Japanese has been slightly rewritten to make it easier to translate into English.)
We recently considered making the site multilingual. In WordPress, there is a multilingualization plugin called BOGO. With this plugin, you can switch between the Japanese top page and the English top page.
By the way, the category widget has an option to show the number of posts that each category has.If you use BOGO, this number of posts will not be a language-specific number. What we think about this time is how to match the number of posts to the language being displayed.
Table of Contents
- About the test environment
- Prepare categories and articles
- Points of focus
- Implementation
About the test environment
We installed XAMPP on our Windows 10 laptop to display WordPress.
For WordPress, which we used for our test, the situation is as follows.
- WordPress 5.6.2
- BOGO 3.5
- Parent theme: Twenty Twenty-One 1.1
- Child theme: A child theme with just the above as the parent theme
The child theme just contains style.css and functions.php.
We added a description to the function.php of the child theme this time. And we switched the number of posts displayed in the category widget by language.
The language settings for BOGO are as follows
Language | Status |
---|---|
Japanese [ja] | Site Language |
English (United States) [en_US] | Active |
In this setting, the language of the site is Japanese and the language of the destination is only English.
Sponsored Links
Prepare categories and articles
The following categories were created. (Japanese)
カテゴリー0001 - カテゴリー0001-0001 - カテゴリー0001-0002
This is the situation where “カテゴリー0001” has two child categories.
The English translation of the above was set as follows.
Japanese | English |
---|---|
カテゴリー0001 | category0001 |
カテゴリー0001-0001 | category0001-0001 |
カテゴリー0001-0002 | category0001-0002 |
The article was created as follows.
Article Title. | Language | Category |
---|---|---|
タイトル:0001 | ja | カテゴリー0001-0001 |
… | … | … |
タイトル:0010 | ja | カテゴリー0001-0001 |
title: 0001 | en_US | カテゴリー0001-0001 |
タイトル:0011 | ja | カテゴリー0001-0002 |
Category 0001-0001 contains 10 articles in Japanese and 1 article in English. There are 1 Japanese articles in category 0001-0002. There are 0 articles in English in category 0001-0002 as follows.
Category | Number of Japanese articles | Number of English articles |
---|---|---|
カテゴリー0001-0001 | 10 | 1 |
カテゴリー0001-0002 | 1 | 0 |
Let’s take a look at the value of the number of posts displayed in the category widget for each of the Japanese and English pages of BOGO. The total number of posts is displayed without distinguishing between languages.
Japanese page
カテゴリー0001 (12)
カテゴリー0001-0001 (11)
カテゴリー0001-0002 (1)
English page
category0001 (12)
category0001-0001 (11)
category0001-0002 (1)


As you can see in these screen captures, the number of posts is displayed the same on the Japanese and English pages.
Points of focus
How do we change the number of posts in the category widget? We roughly read the processing of the function called in this widget.
There is a function called walk_category_tree() defined in category-template.php in the wp-includes folder. This function is called.
It is defined as follows.
Excerpt from walk_category_tree()
function walk_category_tree( ...$args ) {
// The user's options are the third parameter.
if ( empty( $args[2]['walker'] ) || ! ( $args[2]['walker'] instanceof Walker ) ) {
$walker = new Walker_Category;
} else {
/**
* @var Walker $walker
*/
$walker = $args[2]['walker'];
}
return $walker->walk( ...$args );
}
The argument $args[0] contains an array of WP_Term Objects. In this situation, it is stored as follows.
$argsのindex 0
Array
(
[0] => WP_Term Object
(
[term_id] => 2
[name] => カテゴリー0001
[slug] => cat-0001
[term_group] => 0
[term_taxonomy_id] => 2
[taxonomy] => category
[description] =>
[parent] => 0
[count] => 12
[filter] => raw
[cat_ID] => 2
[category_count] => 12
[category_description] =>
[cat_name] => カテゴリー0001
[category_nicename] => cat-0001
[category_parent] => 0
)
[1] => WP_Term Object
(
...
)
[2] => WP_Term Object
(
...
)
)
The property count is the number of posts displayed in the category widget.
Notice the contents of the if-else statements. If an instance of the Walker class is stored in the argument $args[2][‘walker], it is retrieved. In the case of category widgets, $args[2][‘walker] is empty. The process moves to the block of if statements above. The Walker_Category class generates the html for display.
Walker_Category is defined in class-walker-category.php. The comment contains the following description.
Core class used to create an HTML list of categories.
This class stores an instance in the variable $walker and calls the walk method. As commented above, html is returned by this method.
Here we came up with an idea: predefine a class that inherits from the Walker_Category class, and override the walk method.
If we can store an instance of the class in $args[2][‘walker’], we can invoke the walk method of that instance.
As a result of examining the caller of this function, we can see that the apply_filters() function is used in the following places.
Source
public function widget( $args, $instance ) {
.
.
.
wp_list_categories( apply_filters( 'widget_categories_args', $cat_args, $instance ) );
.
.
.
}
As a result of checking, $args[2] of $args argument of walk_category_tree() is $cat_args above. So we can add a filter function to modify the $cat_args.
Implementation
We decided to implement the following policy.
- Create a class that extends the Walker_Category class and override the walk() method. Then, use the walk() method to change the category count.
- Using the filter function, store an instance of the above class in the argument $cat_args of the wp_list_categories() method.
Assuming that BOGO is enabled, we put the following program in the functions.php of our child theme.
ソース
// Extending the class
class My_Walker_Category extends Walker_Category {
public function walk( ...$args ) {
// Setting to search all items by language
$get_posts_arg = array(
'suppress_filters' => false,
'numberposts' => -1,
);
foreach ( $args[0] as $key => $obj ) {
// Setting to specify the category
$get_posts_arg[ 'category' ] = $obj ->cat_ID;
// Get the number of posts
$count = count( get_posts( $get_posts_arg ) );
if ( 0 == $count) {
// If zero, delete the object from the array.
unset( $args[0][$key] );
} else {
// Otherwise, change the value of the property.
$args[0][$key]->count = $count;
}
}
return parent::walk( ...$args );
}
}
// Filter
function widget_categories_args_my_filter( $cat_args, $instance ) {
// Stores an instance.
$cat_args['walker'] = new My_Walker_Category;
return $cat_args;
}
add_filter( 'widget_categories_args', 'widget_categories_args_my_filter', 10, 2 );
The number of posts in a category changed as shown below.
Japanese page
カテゴリー0001 (11)
カテゴリー0001-0001 (10)
カテゴリー0001-0002 (1)
English page
category0001 (1)
category0001-0001 (1)


In the walk() method of the My_Walker_Category class, we adjusted the arguments. The walk() method of the inheritor is called.
The purpose of this time is to change the number of articles in a category. So, we implemented it to change the count property of WP_Term Object included in the argument. The get_posts() method is used to get the number of posts. Since an array is returned, the count() method is used to get the length of the array.
If BOGO is enabled, depending on the arguments passed to the get_posts() method, the posts in the language of the currently displayed page are retrieved. Specifically, by setting the argument property suppress_filters to false, BOGO adds language to the search criteria.
The number of searches is stored in $count and used for conditional branching. This conditional branch is to avoid displaying categories with zero articles. For example, in this case, “Category 0001-0002” has 1 article in Japanese and 0 articles in English.So, in the category widget of the English page, the “Category 0001-0002” itself should not be displayed. In the above program, the unset() method is used to remove the target WP_Term Object from the array.
In the widget_categories_args_my_filter() method, an instance of the My_Walker_Category class is stored in $cat_args. As a result of this process, this instance is used in the walk_category_tree() method.
We implemented it as above, but the get_posts() method is heavy processing. When the number of posts and categories is large, the screen display is slow.
That’s all. I hope this is helpful to you.