Displays archive links based on type and format.
Description
See also
Parameters
$args
string|arrayoptional- Default archive links arguments. Optional.
type
stringType of archive to retrieve. Accepts'daily'
,'weekly'
,'monthly'
,'yearly'
,'postbypost'
, or'alpha'
. Both'postbypost'
and'alpha'
display the same archive link list as well as post titles instead of displaying dates. The difference between the two is that'alpha'
will order by post title and'postbypost'
will order by post date.
Default'monthly'
.limit
string|intNumber of links to limit the query to. Default empty (no limit).format
stringFormat each link should take using the $before and $after args.
Accepts'link'
(<link>
tag),'option'
(<option>
tag),'html'
(<li>
tag), or a custom format, which generates a link anchor with $before preceding and $after succeeding. Default'html'
.before
stringMarkup to prepend to the beginning of each link.after
stringMarkup to append to the end of each link.show_post_count
boolWhether to display the post count alongside the link. Default false.echo
bool|intWhether to echo or return the links list. Default1|true
to echo.order
stringWhether to use ascending or descending order. Accepts'ASC'
, or'DESC'
.
Default'DESC'
.post_type
stringPost type. Default'post'
.year
stringYear. Default current year.monthnum
stringMonth number. Default current month number.day
stringDay. Default current day.w
stringWeek. Default current week.
Default:
''
Source
function wp_get_archives( $args = '' ) {
global $wpdb, $wp_locale;
$defaults = array(
'type' => 'monthly',
'limit' => '',
'format' => 'html',
'before' => '',
'after' => '',
'show_post_count' => false,
'echo' => 1,
'order' => 'DESC',
'post_type' => 'post',
'year' => get_query_var( 'year' ),
'monthnum' => get_query_var( 'monthnum' ),
'day' => get_query_var( 'day' ),
'w' => get_query_var( 'w' ),
);
$parsed_args = wp_parse_args( $args, $defaults );
$post_type_object = get_post_type_object( $parsed_args['post_type'] );
if ( ! is_post_type_viewable( $post_type_object ) ) {
return;
}
$parsed_args['post_type'] = $post_type_object->name;
if ( '' === $parsed_args['type'] ) {
$parsed_args['type'] = 'monthly';
}
if ( ! empty( $parsed_args['limit'] ) ) {
$parsed_args['limit'] = absint( $parsed_args['limit'] );
$parsed_args['limit'] = ' LIMIT ' . $parsed_args['limit'];
}
$order = strtoupper( $parsed_args['order'] );
if ( 'ASC' !== $order ) {
$order = 'DESC';
}
// This is what will separate dates on weekly archive links.
$archive_week_separator = '–';
$sql_where = $wpdb->prepare( "WHERE post_type = %s AND post_status = 'publish'", $parsed_args['post_type'] );
/**
* Filters the SQL WHERE clause for retrieving archives.
*
* @since 2.2.0
*
* @param string $sql_where Portion of SQL query containing the WHERE clause.
* @param array $parsed_args An array of default arguments.
*/
$where = apply_filters( 'getarchives_where', $sql_where, $parsed_args );
/**
* Filters the SQL JOIN clause for retrieving archives.
*
* @since 2.2.0
*
* @param string $sql_join Portion of SQL query containing JOIN clause.
* @param array $parsed_args An array of default arguments.
*/
$join = apply_filters( 'getarchives_join', '', $parsed_args );
$output = '';
$last_changed = wp_cache_get_last_changed( 'posts' );
$limit = $parsed_args['limit'];
if ( 'monthly' === $parsed_args['type'] ) {
$query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date $order $limit";
$key = md5( $query );
$key = "wp_get_archives:$key:$last_changed";
$results = wp_cache_get( $key, 'post-queries' );
if ( ! $results ) {
$results = $wpdb->get_results( $query );
wp_cache_set( $key, $results, 'post-queries' );
}
if ( $results ) {
$after = $parsed_args['after'];
foreach ( (array) $results as $result ) {
$url = get_month_link( $result->year, $result->month );
if ( 'post' !== $parsed_args['post_type'] ) {
$url = add_query_arg( 'post_type', $parsed_args['post_type'], $url );
}
/* translators: 1: Month name, 2: 4-digit year. */
$text = sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $result->month ), $result->year );
if ( $parsed_args['show_post_count'] ) {
$parsed_args['after'] = ' (' . $result->posts . ')' . $after;
}
$selected = is_archive() && (string) $parsed_args['year'] === $result->year && (string) $parsed_args['monthnum'] === $result->month;
$output .= get_archives_link( $url, $text, $parsed_args['format'], $parsed_args['before'], $parsed_args['after'], $selected );
}
}
} elseif ( 'yearly' === $parsed_args['type'] ) {
$query = "SELECT YEAR(post_date) AS `year`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date) ORDER BY post_date $order $limit";
$key = md5( $query );
$key = "wp_get_archives:$key:$last_changed";
$results = wp_cache_get( $key, 'post-queries' );
if ( ! $results ) {
$results = $wpdb->get_results( $query );
wp_cache_set( $key, $results, 'post-queries' );
}
if ( $results ) {
$after = $parsed_args['after'];
foreach ( (array) $results as $result ) {
$url = get_year_link( $result->year );
if ( 'post' !== $parsed_args['post_type'] ) {
$url = add_query_arg( 'post_type', $parsed_args['post_type'], $url );
}
$text = sprintf( '%d', $result->year );
if ( $parsed_args['show_post_count'] ) {
$parsed_args['after'] = ' (' . $result->posts . ')' . $after;
}
$selected = is_archive() && (string) $parsed_args['year'] === $result->year;
$output .= get_archives_link( $url, $text, $parsed_args['format'], $parsed_args['before'], $parsed_args['after'], $selected );
}
}
} elseif ( 'daily' === $parsed_args['type'] ) {
$query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, DAYOFMONTH(post_date) AS `dayofmonth`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date), DAYOFMONTH(post_date) ORDER BY post_date $order $limit";
$key = md5( $query );
$key = "wp_get_archives:$key:$last_changed";
$results = wp_cache_get( $key, 'post-queries' );
if ( ! $results ) {
$results = $wpdb->get_results( $query );
wp_cache_set( $key, $results, 'post-queries' );
}
if ( $results ) {
$after = $parsed_args['after'];
foreach ( (array) $results as $result ) {
$url = get_day_link( $result->year, $result->month, $result->dayofmonth );
if ( 'post' !== $parsed_args['post_type'] ) {
$url = add_query_arg( 'post_type', $parsed_args['post_type'], $url );
}
$date = sprintf( '%1$d-%2$02d-%3$02d 00:00:00', $result->year, $result->month, $result->dayofmonth );
$text = mysql2date( get_option( 'date_format' ), $date );
if ( $parsed_args['show_post_count'] ) {
$parsed_args['after'] = ' (' . $result->posts . ')' . $after;
}
$selected = is_archive() && (string) $parsed_args['year'] === $result->year && (string) $parsed_args['monthnum'] === $result->month && (string) $parsed_args['day'] === $result->dayofmonth;
$output .= get_archives_link( $url, $text, $parsed_args['format'], $parsed_args['before'], $parsed_args['after'], $selected );
}
}
} elseif ( 'weekly' === $parsed_args['type'] ) {
$week = _wp_mysql_week( '`post_date`' );
$query = "SELECT DISTINCT $week AS `week`, YEAR( `post_date` ) AS `yr`, DATE_FORMAT( `post_date`, '%Y-%m-%d' ) AS `yyyymmdd`, count( `ID` ) AS `posts` FROM `$wpdb->posts` $join $where GROUP BY $week, YEAR( `post_date` ) ORDER BY `post_date` $order $limit";
$key = md5( $query );
$key = "wp_get_archives:$key:$last_changed";
$results = wp_cache_get( $key, 'post-queries' );
if ( ! $results ) {
$results = $wpdb->get_results( $query );
wp_cache_set( $key, $results, 'post-queries' );
}
$arc_w_last = '';
if ( $results ) {
$after = $parsed_args['after'];
foreach ( (array) $results as $result ) {
if ( $result->week != $arc_w_last ) {
$arc_year = $result->yr;
$arc_w_last = $result->week;
$arc_week = get_weekstartend( $result->yyyymmdd, get_option( 'start_of_week' ) );
$arc_week_start = date_i18n( get_option( 'date_format' ), $arc_week['start'] );
$arc_week_end = date_i18n( get_option( 'date_format' ), $arc_week['end'] );
$url = add_query_arg(
array(
'm' => $arc_year,
'w' => $result->week,
),
home_url( '/' )
);
if ( 'post' !== $parsed_args['post_type'] ) {
$url = add_query_arg( 'post_type', $parsed_args['post_type'], $url );
}
$text = $arc_week_start . $archive_week_separator . $arc_week_end;
if ( $parsed_args['show_post_count'] ) {
$parsed_args['after'] = ' (' . $result->posts . ')' . $after;
}
$selected = is_archive() && (string) $parsed_args['year'] === $result->yr && (string) $parsed_args['w'] === $result->week;
$output .= get_archives_link( $url, $text, $parsed_args['format'], $parsed_args['before'], $parsed_args['after'], $selected );
}
}
}
} elseif ( ( 'postbypost' === $parsed_args['type'] ) || ( 'alpha' === $parsed_args['type'] ) ) {
$orderby = ( 'alpha' === $parsed_args['type'] ) ? 'post_title ASC ' : 'post_date DESC, ID DESC ';
$query = "SELECT * FROM $wpdb->posts $join $where ORDER BY $orderby $limit";
$key = md5( $query );
$key = "wp_get_archives:$key:$last_changed";
$results = wp_cache_get( $key, 'post-queries' );
if ( ! $results ) {
$results = $wpdb->get_results( $query );
wp_cache_set( $key, $results, 'post-queries' );
}
if ( $results ) {
foreach ( (array) $results as $result ) {
if ( '0000-00-00 00:00:00' !== $result->post_date ) {
$url = get_permalink( $result );
if ( $result->post_title ) {
/** This filter is documented in wp-includes/post-template.php */
$text = strip_tags( apply_filters( 'the_title', $result->post_title, $result->ID ) );
} else {
$text = $result->ID;
}
$selected = get_the_ID() === $result->ID;
$output .= get_archives_link( $url, $text, $parsed_args['format'], $parsed_args['before'], $parsed_args['after'], $selected );
}
}
}
}
if ( $parsed_args['echo'] ) {
echo $output;
} else {
return $output;
}
}
Hooks
- apply_filters( ‘getarchives_join’,
string $sql_join ,array $parsed_args ) Filters the SQL JOIN clause for retrieving archives.
- apply_filters( ‘getarchives_where’,
string $sql_where ,array $parsed_args ) Filters the SQL WHERE clause for retrieving archives.
- apply_filters( ‘the_title’,
string $post_title ,int $post_id ) Filters the post title.
To filter a specific category/term, we have a specific case to add filters. It works in case we wish to change archive link based on get_query_var(‘news_category’).
For example, on same template we have:
– News Category #1 has dropdown of 2019, 2018, 2017.
– News Category #2 has dropdown of 2017.
If the user access /news/news-category-2/2019, it will return no posts. We should disable an archive link 2018, 2019 if a current category is News Category.
The below code work with Taxonomy “news_category” and custom post type “news”. To work with default post, you should change back to Taxonomy “category” and default post “post”.
In templates/custom-archive-template.php
In functions.php:
Read more about https://developer.wordpress.org/reference/hooks/getarchives_where/ and https://developer.wordpress.org/reference/hooks/getarchives_join/
Display list of links to last two weeks of daily archives
Lists last 14 days that had at least one post, with count total for each day in parentheses, e.g. “November 2, 2015 (3)”.
Dropdown Box
Displays a dropdown menu of monthly archives, in option tags, with the post count (uses JavaScript to navigate to the selected archive page).
To return an array of years with name and value only like:
We must capture using
echo=false&format=custom
:Default Usage
Display list of links to last 12 months of archives
Display the titles of the last 20 posts
Uses
custom
as the value for theformat
argument and specifiesbefore
andafter
values (so, in this example, prints the titles within span tags and separated by commas):Display linked titles of all posts, listed alphabetically
Of possible use on a sitemap.
An example using custom wrappers on each link item in the archive. Helpful if you are doing special styling that require a more complicated structure.