3

I want to display the post archives like seen in this picture. Shown by year and on click it should open up the months. I am not sure how to approach this, would you customize the standard WordPress Archives Widget?

enter image description here

2 Answers 2

2

I did this for a client and it looked like this:

The PHP code:

<dl class="tree-accordion">
    <?php
    $currentyear = date("Y");
    $years = range($currentyear, 1950);
    foreach($years as $year) { ?>
        <dt><a href=""><i class="fa fa-fw fa-plus-square-o" aria-hidden="true"></i> <?php echo $year; ?></a></dt>
        <?php
        $archi = wp_get_archives('echo=0&show_post_count=1&type=monthly&year=' . $year);
        $archi = explode('</li>', $archi);
        $links = array();
        foreach($archi as $link) {
            $link = str_replace(array('<li>', "\n", "\t", "\s"), '' , $link);
            if('' != $link)
                $links[] = $link;
            else
                continue;
        }
        $fliplinks = array_reverse($links);
        if(!empty($fliplinks)) {
            echo '<dd>';
            foreach($fliplinks as $link) {
                echo '<span>' . $link . '</span>';
            }
            echo '</dd>';
        } else {
            echo '<dd class="tree-accordion-empty"></dd>';
        }
        ?>
    <?php } ?>
</dl>

The archives override filter:

/*
 * Add filter to query archives by year
 */
function newmarket_getarchives_filter($where, $args) {
    if(isset($args['year'])) {
        $where .= ' AND YEAR(post_date) = ' . intval($args['year']);
    }

    return $where;
}

add_filter('getarchives_where', 'newmarket_getarchives_filter', 10, 2);

The CSS code:

.tree-accordion {
    line-height: 1.5;
}
.tree-accordion dt, .tree-accordion dd {}
.tree-accordion dt a {
    display: block;
}
.tree-accordion .fa {
    color: #666666;
}
.tree-accordion dd a {}
.tree-accordion dd span {
    display: block;
}
.tree-accordion dd {
    margin: 0 0 0 20px;
}

The Javascript code:

jQuery(document).ready(function(){
    var allPanels = jQuery('.tree-accordion > dd').hide();

    jQuery('.tree-accordion > dt > a').click(function() {
        $target = jQuery(this).parent().next();

        if(!$target.hasClass('active')) {
            allPanels.removeClass('active').slideUp();
            $target.addClass('active').slideDown(100);
        }

        return false;
    });

    jQuery('.tree-accordion-empty').prev().hide();
});

UPDATE: Remove year after month:

Change this line:

$link = str_replace(array('<li>', "\n", "\t", "\s"), '' , $link);

To:

$link = str_replace(array('<li>', "\n", "\t", "\s"), '', $link);
$link = str_replace($year, '', $link);

The final result:

enter image description here

3
  • as per the OP question, OP only wanted to show a month. but as per your code also displaying year after the month. how can I remove year after month?
    – Bhautik
    Aug 11, 2020 at 16:57
  • 1
    @Bhautik check my update above.
    – Ciprian
    Aug 12, 2020 at 14:51
  • 1
    Thank You for coming back and updating your answer.
    – Bhautik
    Aug 13, 2020 at 8:23
-1

The "Archives" Widget makes use of wp_get_archives() which, given the correct arguments (specifically the format argument), can supply the markup you need. I'd say customizing that Widget is a good place to start.

3
  • The wp_get_archives() widget does not allow for such a structure. It only allows for years OR months.
    – Ciprian
    May 15, 2016 at 15:01
  • @Ciprian wp_get_archives() is a function, not a widget. The "Archives" widget can easily be customized to call this function more than once, in order to produce the desired markup. Jun 24, 2016 at 3:27
  • I know it's a function. I actually solved this issue on one of my clients' sites by using a custom function.
    – Ciprian
    Jun 24, 2016 at 10:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.