I want to create a list of posts from a Custom Post Type and add some filters the user can click to filter the list.

I added filters for all the categories by using the get_terms() function. Now I want to add filters by year, so I need a way to retrieve a list of all the years in which at least one post has been published...

I just need something like:

$years = get_all_years_with_posts();
// returns array( 2011, 2013, 2014 )

I know I can grab all the posts, check their year, and build the list myself, but is not there any other approach?


Your question is pretty old, but I just wanted to add a real solution to your question. Here's a function that will return an array of years you have posts published in. You can put this function in functions.php or in a plugin or whatever you want.

function get_posts_years_array() {
    global $wpdb;
    $result = array();
    $years = $wpdb->get_results(
            "SELECT YEAR(post_date) FROM {$wpdb->posts} WHERE post_status = 'publish' GROUP BY YEAR(post_date) DESC"
    if ( is_array( $years ) && count( $years ) > 0 ) {
        foreach ( $years as $year ) {
            $result[] = $year[0];
    return $result;

You'll need to modify it slightly for custom post types... just add AND wp_posts.post_type = 'my_cpt' somewhere in there.

  • Why am I being downvoted? The other answer didn't answer the question. My answer answers the question. – Gavin Jul 28 '17 at 3:22
  • I needed to slightly tweak it. I think prepare() requires you to give at least one format argument %s ( see wordpress.stackexchange.com/a/270970/11914. But worked and upvoted. – yuvilio Apr 5 '18 at 17:33
  • What makes this the real solution? – idleberg Apr 26 at 8:14
  • @idleberg Because at the time I posted my answer, the other person who answered misread the question. They gave an example of how to get all posts sorted by the year, but the OP wanted to get a list of years that have posts. – Gavin May 10 at 6:48

You could use a WP function and a shortcode this way :

add_shortcode( 'archives', '_get_archived_posts' );
function _get_archived_posts( $atts ) {

 $a = shortcode_atts( array(
    'type'            => 'yearly',
    'limit'           => '',
    'format'          => '', 
    'before'          => '',
    'after'           => '',
    'show_post_count' => false,
    'echo'            => 0,
    'order'           => 'DESC'
), $atts, 'filter_archives_sc' );

    return wp_get_archives($a);



You could use this function to get all the post years in a array, which you could use to loop with.

$terms_year = array(
    'post_type'         => array('YOUR_CPT'),

$years = array();
$query_year = new WP_Query( $terms_year );

if ( $query_year->have_posts() ) :
    while ( $query_year->have_posts() ) : $query_year->the_post();
        $year = get_the_date('Y');
        if(!in_array($year, $years)){
            $years[] = $year;

// Echo the years out wherever you want

echo '<pre>';
echo '</pre>';
  • This solution works fine when the typo is fixed (replace $query_jaar with query_year). – idleberg Apr 26 at 8:14
// Get all years posts publish;
function get_posts_years_array($post_type = 'post') {

    global $wpdb;
    $result = array();

    $query_prepare = $wpdb->prepare("SELECT YEAR(post_date) FROM ($wpdb->posts) WHERE post_status = 'publish' AND post_type = %s GROUP BY YEAR(post_date) DESC", $post_type);

    $years = $wpdb->get_results($query_prepare);

    if ( is_array( $years ) && count( $years ) > 0 ) {
        foreach ( $years as $year ) {
            $result[] = json_decode(json_encode($year), true);

    return $result;

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.