If you have seen Queries like those:

	SELECT * FROM wp_posts p
	LEFT OUTER JOIN wp_term_relationships r ON r.object_id = p.ID
	LEFT OUTER JOIN wp_term_taxonomy x ON x.term_taxonomy_id = r.term_taxonomy_id
	LEFT OUTER JOIN wp_terms t ON t.term_id = x.term_id
	WHERE p.post_status = 'publish'
	AND p.post_type = 'post'
	AND t.slug = 'news-archiv'

then you know what i am talking about.

IT’S DAMN HARD!

this is modified plugin:

post-tags-and-archives.php

from http://www.oxpal.com/main.php?o=dev_wordpress_pta

THE INTERESTING PART:

News-Archiv

is the name of the category. We do not want to get any other posts than those in that category.

 

  function wp_get_archives( $args = '' )

does not offer such functionality.

$categoryID = get_cat_ID("News-Archiv");
$args = array(
'category' => $categoryID
);
$posts = get_posts( $args ); // does not return posts sorted by month or year.

$groupData = array();
foreach ( $posts as $post )
{
$date = date_parse($post->post_date);
$groupData[$date['year']][$date['month']][] = $post;
}

THE FULL CODE:

download as tar.gz: post-tags-and-archive.tar

<!--?php /* Plugin Name: Post Tags and Archives Plugin Plugin URI: http://www.oxpal.com/main.php?o=dev_wordpress_pta & https://dwaves.org/2015/08/05/cms-wordpress-display-archived-category-posts-group-by-month-and-year/ Version: 1.7.9 Author: Thomas Schmall & David username Description: Allows you to add the tag cloud and archives into posts and pages. Simply write [POSTTAGS] or [POSTARCHIVES] in the text. Author uri: */ // check for WP context if (! defined ( 'ABSPATH' )) { die (); } // initially set the options function pta_posttagsandarchives_install() { $newoptions = get_option ( 'pta-posttagsandarchives_options' ); $newoptions = pta_getDefaults ( $newoptions ); add_option ( 'pta-posttagsandarchives_options', $newoptions ); return; } // install function pta_getDefaults($optionsArray) { /* * Reference list of arguments for cloud: $args = array( 'smallest' => 8, 'largest' => 22, 'unit' => 'pt', / pt, px, em, % 'number' => 45, number: If its 0 then all are shown` 'format' => 'flat', ('list' (UL) or 'array'(for use in php)) 'separator' => "\n", between text /default: '\n' (whitespace) 'separator' => "\n/\n" 'orderby' => 'name', (count) 'order' => 'ASC', * 'DESC' * 'RAND' tags are in a random order. 'exclude' => null, 'include' => null, 'topic_count_text_callback' => default_topic_count_text, 'link' => 'view', 'taxonomy' => 'post_tag', 'echo' => true );<br ?--> */
$optionsArray ['smallest'] = '10';
$optionsArray ['largest'] = '29';
$optionsArray ['number'] = null;
$optionsArray ['orderby'] = 'name';
$optionsArray ['order'] = 'ASC';
$optionsArray ['exclude'] = null;
$optionsArray ['include'] = null;
$optionsArray ['format'] = 'flat';
$optionsArray ['separator'] = "<span style="color: #efefef;">•</span>";

/* WOULD BE GREAT, IF ONE COULD PICK A CATEGORY IN BACKEND - UNTESTED!
$categories_array = get_categories();

$categories_string = '<select id="category" name="category">';</select>

// serialize
foreach ($categories_array as $key => $value)
{
$categories_string .= 'Volvo';
}

$categories_string .= '';

$optionsArray ['category'] = $categories_string;
*/


/*
* Reference list of arguments for archive: $args = array( <!--?php $args = array( 'type' => 'monthly', yearly, daily, weekly, postbypost, alpha (same as psotbypost but ordered by title) 'limit' => null, (number of archives to get) 'format' => 'html', option, link (only for head, so doesn't apply), custom (uses before and after) 'before' => null, string (text before link) 'after' => null, string (text after link) 'show_post_count' => false, bool (show number of posts/archive) 'echo' => true, false (return out put or echo) 'order' => 'DESC' 'ASC' ); ?-->
*/


$optionsArray ['archives_type'] = 'monthly';
$optionsArray ['archives_limit'] = null;
$optionsArray ['archives_format'] = 'html';
$optionsArray ['archives_before'] = null;
$optionsArray ['archives_after'] = null;
$optionsArray ['archives_show_post_count'] = false;
$optionsArray ['archives_order'] = 'DESC';

return $optionsArray;
}

// add the admin page
function pta_posttagsandarchives_add_pages() {
add_options_page ( 'Post Tags and Archives', 'Post Tags & Archives', 'manage_options', __FILE__, 'pta_posttagsandarchives_options' );
}
function pta_posttagsandarchives_uninstall() {
delete_option ( 'pta-posttagsandarchives_options' );
// delete_option('pta-posttagsandarchives_widget');
if (function_exists ( 'add_shortcode' )) {
remove_shortcode ( 'POSTARCHIVES' );
remove_shortcode ( 'postarchives' );
remove_shortcode ( 'postarchive' );
remove_shortcode ( 'POSTARCHIVE' );
remove_shortcode ( 'posttags' );
remove_shortcode ( 'POSTTAGS' );
}
return;
} // uninstall

// shortcode function
function pta_posttags_shortcode($atts = NULL) {
return pta_GetPostTags ();
}
function pta_postarchives_shortcode($atts = NULL) {
return pta_GetPostArchives ();
}

// php function for integration
function pta_posttags($atts = NULL) {
echo pta_GetPostTags ();
}
function pta_postarchives($atts = NULL) {
echo pta_GetPostArchives ();
}

// replace tag in content with tag cloud (non-shortcode version for WP 2.3.x)
function pta_posttagsandarchives_init($content) {
$postTags = true;
$postArchives = true;

if (strpos ( $content, '[POSTTAGS]' ) === false) {
$postTags = false;
}
;

if (strpos ( $content, '[POSTARCHIVES]' ) === false) {
$postArchives = false;
}
;

if ($postTags) {
$code = pta_GetPostTags ();
$content = str_replace ( '[POSTTAGS]', $code, $content );
}

if ($postArchives) {
$code = pta_GetPostArchive ();
$content = str_replace ( '[POSTARCHIVES]', $code, $content );
}

return $content;
} // init
function pta_GetPostTags() {
$args = pta_posttagsandarchives_getargs ();
$encloseBegin = '
<div class="pta-posttags">'
;
$encloseEnd = '</div>
'
;
// echo $encloseBegin;
$code = $encloseBegin . wp_tag_cloud ( $args ) . $encloseEnd;
return $code;
}
function pta_GetPostArchives() {

$args = pta_posttagsandarchives_getargs_archives();

$tEncloseBegin = "";
$tEncloseEnd = "";
if ($args ['format'] == 'html') {
$tEncloseBegin = "
<ul>
    <li style="
list-style-type: none">
<ul>"
;</ul>
</li>
</ul>
 
<ul>$tEncloseEnd = "</ul>
"
;
}

$encloseBegin = '
<div class="pta-postarchives">'
. $tEncloseBegin;
$encloseEnd = $tEncloseEnd . '</div>
'
;
// echo $encloseBegin;

$categoryID = get_cat_ID("News-Archiv");
$args = array(
'category' => $categoryID
);
$posts = get_posts( $args ); // does not return posts sorted by month or year.

$groupData = array();
foreach ( $posts as $post )
{
$date = date_parse($post->post_date);
$groupData[$date['year']][$date['month']][] = $post;
}

$lang = get_bloginfo('language'); // get lang of current post (i hope so)

if($lang == 'de-DE')
{
$month_names = array(
1=>"Januar",
2=>"Februar",
3=>"März",
4=>"April",
5=>"Mai",
6=>"Juni",
7=>"Juli",
8=>"August",
9=>"September",
10=>"Oktober",
11=>"November",
12=>"Dezember");
}
else // assume english
{
$month_names = array('', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
}

foreach ( $groupData as $year => $month_array )
{
foreach ( $month_array as $month_number => $posts )
{
$month_string = $month_names[$month_number]; // 3 -> March/März
$siteurl = get_site_url();;
$html_output .= '
<ul>
    <li><a href="'
.$siteurl.'/index.php/'.$year.'/'.$month_number.'/">'.$month_string.' '.$year.' ('.count($posts).')</a></li>
</ul>
'
;

/* currently no need to iterate over all posts
foreach ( $posts as $key => $post )
{
print_r($post);
}
*/

}
}

$code = $encloseBegin . $html_output . $encloseEnd;

// $code = $encloseBegin.wp_get_archives($args).$encloseEnd; // convenient, but does not allow to filter out a category 'News-Archiv'

return $code;
}
function pta_posttagsandarchives_getargs() {
$tempoptions = get_option ( 'pta-posttagsandarchives_options' );

$args = array (
'smallest' => $tempoptions ['smallest'],
'largest' => $tempoptions ['largest'],
'number' => $tempoptions ['number'],
'orderby' => $tempoptions ['orderby'],
'order' => $tempoptions ['order'],
'exclude' => $tempoptions ['exclude'],
'include' => $tempoptions ['include'],
'format' => $tempoptions ['format'],
'separator' => "\n" . $tempoptions ['separator'],
'taxonomy' => 'post_tag',
'link' => 'view',
'echo' => false
)
;

return $args;
}
function pta_posttagsandarchives_getargs_archives() {
$tempoptions = get_option ( 'pta-posttagsandarchives_options' );

$args = array (
'type' => $tempoptions ['archives_type'],
'limit' => $tempoptions ['archives_limit'],
'format' => $tempoptions ['archives_format'],
'before' => $tempoptions ['archives_before'],
'after' => $tempoptions ['archives_after'],
'show_post_count' => $tempoptions ['archives_show_post_count'],
'echo' => false,
// 'echo' => $tempoptions['archives_echo'],
'order' => $tempoptions ['archives_order']
);

return $args;
}

// options page
function pta_posttagsandarchives_options() {
$options = $newoptions = get_option ( 'pta-posttagsandarchives_options' );
// if submitted, process results
if ($_POST ["pta-posttagsandarchives_submit"]) {
$arrayDefaults = array ();
$arrayDefaults = pta_getDefaults ( $arrayDefaults );

$tVal = null;

// Tags
$tVal = strip_tags ( stripslashes ( $_POST ["smallest"] ) );
$newoptions ['smallest'] = is_numeric ( $tVal ) ? $tVal : $arrayDefaults ["smallest"];

$tVal = strip_tags ( stripslashes ( $_POST ["largest"] ) );
$newoptions ['largest'] = is_numeric ( $tVal ) ? $tVal : $arrayDefaults ["largest"];

$tVal = strip_tags ( stripslashes ( $_POST ["number"] ) );
$newoptions ['number'] = is_numeric ( $tVal ) ? $tVal : $arrayDefaults ["number"];

$newoptions ['orderby'] = strip_tags ( stripslashes ( $_POST ["orderby"] ) );
$newoptions ['order'] = strip_tags ( stripslashes ( $_POST ["order"] ) );
// $newoptions['exclude'] = strip_tags(stripslashes($_POST["exclude"]));
// $newoptions['include'] = strip_tags(stripslashes($_POST["include"]));

$tstring = html_entity_decode ( stripslashes ( $_POST ["separator"] ) );
$tstring = str_replace ( "\\n", "\n", $tstring );
$newoptions ['separator'] = $tstring;

// archive
$newoptions ['archives_type'] = strip_tags ( stripslashes ( $_POST ["archives_type"] ) );
$tVal = strip_tags ( stripslashes ( $_POST ["archives_limit"] ) );
if (! is_numeric ( $tVal ))
$tVal = $arrayDefaults ["archives_limit"];
if ($tVal == 0)
$tVal = null;
$newoptions ['archives_limit'] = $tVal;
$newoptions ['archives_format'] = strip_tags ( stripslashes ( $_POST ["archives_format"] ) );

$tstring = html_entity_decode ( stripslashes ( $_POST ["archives_before"] ) );
$tstring = str_replace ( "\\n", "\n", $tstring );
$newoptions ['archives_before'] = $tstring;

$tstring = html_entity_decode ( stripslashes ( $_POST ["archives_after"] ) );
$tstring = str_replace ( "\\n", "\n", $tstring );
$newoptions ['archives_after'] = $tstring;

$newoptions ['archives_show_post_count'] = $_POST ["archives_show_post_count"];

$newoptions ['archives_order'] = $_POST ["archives_order"];

echo '
<div id="message" class="updated fade">

'
. __ ( 'Options changed.', 'pta-posttagsandarchives' ) . '

</div>
'
;
}

// any changes? save!
if ($options != $newoptions) {
$options = $newoptions;
update_option ( 'pta-posttagsandarchives_options', $options );
}

// options form
echo '

<form method="post">'
;
echo '
<h3>Post Tags And Archives - Plugin Options</h3>
'
;
echo "
<div class="
\"wrap\"">
<h2>Tag Cloud Options</h2>
";
echo '

';// smallestecho '';
echo '';
// largest
echo '';
echo '';
// number
echo '';
$tVal = $options ['number'];
if ($tVal == null)
$tVal = 0;
echo '';
// orderby
echo '';
echo '';
// order
echo '';
echo '';/*
* //exclude echo ''; echo ''; //include echo ''; echo '';
*/// Separator
echo '';
$tstring = htmlentities ( $options ['separator'] );
$tstring = str_replace ( "
\n", "\\n", $tstring );
echo '';echo '
<table class="
form-table">
<tbody>
<tr valign="
top">
<th scope="
row">Text size of smallest tag</th>
<td><input name="
smallest" size="5" type="text" value="' . $options ['smallest'] . '" />  Size of the tag with the smallest count value - unit is pixel (px).</td>
</tr>
<tr valign="
top">
<th scope="
row">Text size of largest tag</th>
<td><input name="
largest" size="5" type="text" value="' . $options ['largest'] . '" />  Size of the tag with the highest count value - unit is pixel (px).</td>
</tr>
<tr valign="
top">
<th scope="
row">The number of tags to display.</th>
<td><input name="
number" size="8" type="text" value="' . $tVal . '" />  The value 0 means all tags are displayed.</td>
</tr>
<tr valign="
top">
<th scope="
row">Order by:</th>
<td><input checked="
checked" name="orderby" type="radio" value="name" /> Name
<input checked="
checked" name="orderby" type="radio" value="count" /> Count</td>
</tr>
<tr valign="
top">
<th scope="
row">Order direction:</th>
<td><select name="
order">';</select>
<select name="
order">echo '<option '; if ($options ['order'] == 'ASC') { echo ' selected="selected" '; } echo 'value="ASC">Ascending<option '; if ($options ['order'] == 'DESC') { echo ' selected="selected" '; } echo 'value="DESC">Descending<option '; if ($options ['order'] == 'RAND') { echo ' selected="selected" '; } echo 'value="RAND">Random';</select>
<select name="
order">echo '></select></td>
</tr>
<tr valign="
top">
<th scope="
row">Exclude tags</th>
<td><input name="
exclude" size="60" type="text" value="'.$options['exclude'].'" />
List of excluded tags.</td>
</tr>
<tr valign="
top">
<th scope="
row">Include tags</th>
<td><input name="
include" size="60" type="text" value="'.$options['include'].'" />
List of included tags.</td>
</tr>
<tr valign="
top">
<th scope="
row">Separator between tags:

<i>Advanced! Test before using.</i></th>
<td><input name="
separator" size="60" type="text" value="' . $tstring . '" />
Default: <b><span style='color: #efefef;'>&bull;</span></b></td>
</tr>
</tbody>
</table>
';
echo '';

echo "

<div class="\"wrap\"">
<h2>Post Archives Options</h2>
";
echo '

';// typeecho '';
echo '';// format
echo '';
echo '';// limit
$tstring = $options ['archives_limit'] == null ? 0 : $options ['archives_limit'];
echo '';
echo '';// show_post_count
echo '';
echo '';// order
echo '';
echo '';// Custom Strings
echo '';
$tstring = htmlentities ( $options ['archives_before'] );
$tstring = str_replace ( "
\n", "\\n", $tstring );
echo '';
$tstring = htmlentities ( $options ['archives_after'] );
$tstring = str_replace ( "
\n", "\\n", $tstring );
echo '';echo '
<table class="
form-table">
<tbody>
<tr valign="
top">
<th scope="
row">Type of archive list to show:</th>
<td><select name="
archives_type">';</select>
<select name="
archives_type">echo '<option '; if ($options ['archives_type'] == 'yearly') { echo ' selected="selected"'; } echo 'value="yearly">Yearly';</select>
<select name="
archives_type">echo '<option '; if ($options ['archives_type'] == 'monthly') { echo ' selected="selected"'; } echo 'value="monthly">Monthly';</select>
<select name="
archives_type">echo '<option '; if ($options ['archives_type'] == 'weekly') { echo ' selected="selected"'; } echo 'value="weekly">Weekly';</select>
<select name="
archives_type">echo '<option '; if ($options ['archives_type'] == 'daily') { echo ' selected="selected"'; } echo 'value="daily">Daily';</select>
<select name="
archives_type">echo '<option '; if ($options ['archives_type'] == 'postbypost') { echo ' selected="selected"'; } echo 'value="postbypost">All posts (sorted by date)';</select>
<select name="
archives_type">echo '<option '; if ($options ['archives_type'] == 'alpha') { echo ' selected="selected"'; } echo 'value="alpha">All posts (sorted by title)';</select>
<select name="
archives_type">echo '</select>';
// <label for="
stats_order">Limit:</label>';
echo '</td>
</tr>
<tr valign="
top">
<th scope="
row">Format as:</th>
<td><select name="
archives_format">';</select>
<select name="
archives_format">echo '<option '; if ($options ['archives_format'] == 'html') { echo ' selected="selected"'; } echo 'value="html">List (and custom strings) ';</select>
<select name="
archives_format">echo '<option '; if ($options ['archives_format'] == 'option') { echo ' selected="selected"'; } echo 'value="option">Advanced: Options for dropdown';</select>
<select name="
archives_format">echo '<option '; if ($options ['archives_format'] == 'custom') { echo ' selected="selected"'; } echo 'value="custom">Advanced: Use custom strings';</select>
<select name="
archives_format">//</select><label for="stats_order">Limit:</label><select name="archives_format">';</select>
<select name="
archives_format">echo '</select></td>
</tr>
<tr valign="
top">
<th scope="
row">Number of archives to show:</th>
<td><input name="
archives_limit" size="5" type="text" value="' . $tstring . '" />';
echo '<label for="
archives_limit">  The value 0 means no limit.</label>';
echo '</td>
</tr>
<tr valign="
top">
<th scope="
row">Show number of posts per archive?</th>
<td><input id="
archives_show_post_count" checked="checked" name="archives_show_post_count" type="checkbox" value="1" />';
echo '</td>
</tr>
<tr valign="
top">
<th scope="
row">Order direction:</th>
<td><input checked="
checked" name="archives_order" type="radio" value="ASC" /> Ascending
<input checked="
checked" name="archives_order" type="radio" value="DESC" /> Descending
';
echo '</td>
</tr>
<tr valign="
top">
<th scope="
row">Custom strings:

<i>Advanced! Test before using.</i></th>
<td width="
60px"><input name="archives_before" size="40" type="text" value="' . $tstring . '" />';
echo '
Html before item. (Default ist empty)';echo '</td>
<td><input name="
archives_after" size="40" type="text" value="' . $tstring . '" />
Html after item. (Default is empty)';
echo '</td>
</tr>
</tbody>
</table>
';

echo '<input name="
pta-posttagsandarchives_submit" type="hidden" value="true" />';
echo '

';
echo '
<p class="
submit"><input type="submit" value="Update Options »" /></p>
';
echo "


</div>
";
echo '

</div>
</form>';
}

// add the actions
add_action ( 'admin_menu', 'pta_posttagsandarchives_add_pages' );
register_activation_hook ( __FILE__, 'pta_posttagsandarchives_install' );
register_deactivation_hook ( __FILE__, 'pta_posttagsandarchives_uninstall' );

if (function_exists ( 'add_shortcode' )) {
add_shortcode ( 'POSTARCHIVES', 'pta_postarchives_shortcode' );
add_shortcode ( 'postarchives', 'pta_postarchives_shortcode' );
add_shortcode ( 'postarchive', 'pta_postarchives_shortcode' );
add_shortcode ( 'POSTARCHIVE', 'pta_postarchives_shortcode' );
add_shortcode ( 'posttags', 'pta_posttags_shortcode' );
add_shortcode ( 'POSTTAGS', 'pta_posttags_shortcode' );
} else {
add_filter ( 'the_content', 'pta_posttagsandarchives_init' );
}

// Wordpress version check
// maybe one day
/*
* if (version_compare($wp_version, '2.5.0', '<')) add_action('admin_notices', wpp_update_warning')); function wpp_update_warning() { $msg = '
<div id="
wpp-message" class="error fade">

'.__('Your Wordpress version is too old. WP Post Tags And Archives requires at least version 2.5 to function correctly. Please update your blog via Tools > Upgrade.', 'pta-posttagsandarchives').'

</div>
'; echo trim($msg); }
*/
?>
admin