Count the number of posts in monthly archive in the current language only in Bogo

As mentioned in the previous article, it is now possible to count the number of posts in each language for categories, so I thought about doing the same for archive lists. I thought that if I could hook wp_get_archives in the same way as I hooked wp_list_categories for categories then I can use the same method. However, for some reason, add_filter (‘wp_get_archives’) didn’t seem to work. Bogo users must be having the same problem as with categories, but I don’t know why, I couldn’t find any solutions for the number of archived articles even after searching through Internet. I tried to find a solution by directly editing the widget source code, but it was beyond my abilities.

I started to think that it would be faster to create the archive list from scratch using the flexible WP_Query instead of using wp_get_archives, which cannot be filtered in any way. After searching for information, I found several people who shared the source code for creating their own archive list without using wp_get_archives, motivated by the desire to create an archive list for a specific category. I thought it would be difficult to create a pull-down list, but it seems that even this can be achieved with surprisingly simple code. I’ve decided to copy the method used in this blog because of the simplicity of the code and the ease of writing it. https://oz-style.com/train/941/

I want to display it in the sidebar in the same way as a normal archive widget, so I write PHP code in the text widget. On this site, I added the following code to functions.php to make the widget work with PHP.

// enable php code in text widget
function widget_text_exec_php( $widget_text ) {
if( strpos( $widget_text, '<' . '?' ) !== false ) {
ob_start();
eval( '?>' . $widget_text );
$widget_text = ob_get_contents();
ob_end_clean();
}
return $widget_text;
}
add_filter( 'widget_text', 'widget_text_exec_php', 99 );

(Postscript: 2024-10-02: Using this code caused a warning to appear constantly and the error log to fill up. It looks like it’s working fine on the screen. ChatGPT says that this is because $post, which is used in eval, is undefined. If you add “global $post;” to the line before the “eval ” , it seems that the warning will stop appearing. However, according to ChatGPT, “There is a method of using eval() as a code to execute PHP code in a widget, but this is not recommended because it is very risky. It is better to use a plugin such as PHP Code Widget instead. However, I found that this plugin has not been updated for 2 and a half years, so I hesitate to use it. There is also the Code Snippets plugin recommended by JIG creator Firsh, so I tried using that, but to my surprise! there was a fatal error that caused the entire site to crash.  It’s a well-regarded plugin, and I think there was a specific cause on my end, but the damage was too great, so I didn’t feel like trying it again. When I thought about it, this site have a feature that enables shortcodes to run PHP, so I wrote the shortcode in the text widget and saved the PHP code below separately in the theme folder and called it up. (This allowed me to avoid using eval. )

The original code creates monthly archives for specific categories, so I needed to delete all the category-related descriptions. Then I added a parameter called ‘lang’ => $lang that specifies the language code, and then used WP_Query to search. The URL of the monthly archive that you are taken to when you click on it must be changed according to the permalink structure of each site. In the case of this site, the permalink uses the post title. So it must be such as https://www.1wishyouwerehere.com/2024/9. As a result of trial and error, the following code works in the same way as the stock archive widget.

<?php
$lang = get_locale();
$args = array(
'lang' => $lang,
'posts_per_page' => -1 //現在の言語の記事を全部出力
);
$the_query = new WP_Query( $args ); //上記アーカイブクエリを実行
?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<?php $archive_list[ get_the_time( 'Y/n', $post->ID ) ][] = $post->post_title;//年月ごとに記事情報を格納
?>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>

<?php if( $archive_list ) : ?>
<select id="hoge"><!-- hogeは任意の名前:後述のJavaScriptで必要です -->
<option>月を選択</option>
<?php foreach( $archive_list as $year_month => $archive ) :
$year_month_arr = explode( '/', $year_month );
?>
<option value="<?php echo esc_url( home_url( ''.$year_month) ) ?>">
<!-- 現在の言語のアーカイブのURLを value に格納 -->
<?php echo $year_month_arr[0].'年'.$year_month_arr[1].'月' ?> [<?php echo count( $archive ) ?>]
</option>
<?php endforeach; ?>
</select>
<?php endif; ?>


<?php
echo "
<script>
jQuery(function($) {
$('#hoge').change(function() {
if ($(this).val() != '') {
window.location.href = $(this).val();
}
});
});
</script>";
?>

This is what the widget looks like when it has been implemented. Even when there is an English translated posts, the number of posts is still displayed as [1], and only Japanese articles are counted correctly.

The title and date display are in Japanese format, so they cannot be used on the English page as they are. I copied the entire code and made another text widget for English, changed the title to English, and used Bogo’s options to display different widgets on the Japanese and English pages. Just showing the Month as a number like “2024/9” doesn’t appear nice, so I hired single line code that transforms monthly number to English month name with referring to this site: https://www.php.cn/ja/faq/717862.html

<?php
$lang = get_locale();
$args = array(
'lang' => $lang,
'posts_per_page' => -1 //現在の言語の記事を全部出力
);
$the_query = new WP_Query( $args ); //上記アーカイブクエリを実行
?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<?php $archive_list[ get_the_time( 'Y/n', $post->ID ) ][] = $post->post_title;//年月ごとに記事情報を格納
?>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>

<?php if( $archive_list ) : ?>
<select id="hoge"><!-- hogeは任意の名前:後述のJavaScriptで必要です -->
<option>Select Month</option>
<?php foreach( $archive_list as $year_month => $archive ) :
$year_month_arr = explode( '/', $year_month );
?>
<option value="<?php echo esc_url( home_url( $year_month ) ) ?>">
<?php $month_name = date('F', strtotime("1-$year_month_arr[1]-2022"));?>
<?php echo $year_month_arr[0].'-'.$month_name.' ' ?> [<?php echo count( $archive ) ?>]
</option>
<?php endforeach; ?>
</select>
<?php endif; ?>

<?php
echo "
<script>
jQuery(function($) {
$('#hoge').change(function() {
if ($(this).val() != '') {
window.location.href = $(this).val();
}
});
});
</script>";
?>

This shows the appearance of the English version. As you can see, it doesn’t display the months with Japanese-language articles only, such as September 2021, and you can confirm that the count is now correct.

In this way, I was able to display a pull-down archive list in the sidebar with a simpler code than I had expected. I’m actually a little surprised that the stock archive widget requires such a complicated code, but perhaps there are other issues with this method, such as it being too heavy. As always, I’m grateful to the ideas and wisdom of the multiple programmers who helped me to achieve what I wanted to do.

Comment

タイトルとURLをコピーしました