Skip to content

Instantly share code, notes, and snippets.

@damiencarbery
Last active September 9, 2020 12:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save damiencarbery/acc7008031845b02e69c13642506ccbd to your computer and use it in GitHub Desktop.
Save damiencarbery/acc7008031845b02e69c13642506ccbd to your computer and use it in GitHub Desktop.
Truncated Archives Widget - A variation on the core Archives widget where it is like a yearly list in addition to the months of the current year. https://www.damiencarbery.com/2020/09/truncated-archives-widget/
<?php
/*
Plugin Name: Truncated Archives Widget
Plugin URI: https://www.damiencarbery.com/2020/09/truncated-archives-widget/
Description: A variation on the core Archives widget where it is like a yearly list in addition to the months of the current year.
Author: Damien Carbery
Version: 0.1
*/
class Truncated_Archives_Widget extends WP_Widget {
/**
* Holds widget settings defaults, populated in constructor.
*
* @var array
*/
protected $defaults;
private $this_year;
/**
* Constructor. Set the default widget options and create widget.
*
* @since 1.0.0
*/
public function __construct() {
$this->this_year = date( 'Y' );
$this->defaults = [
'title' => '',
'remove_year_suffix' => 0,
'include_this_year' => 1,
];
$widget_ops = [
'classname' => 'truncated-archives-widget widget_archive',
'description' => __( 'A yearly archive of your site with months of current year.', 'taw_widget' ),
];
parent::__construct( 'truncated-archives-widget', __( 'Truncated Archives', 'taw_widget' ), $widget_ops );
}
// Filter the array to exclude strings that do not have the current year.
function archive_exclude_previous_years($item) {
// Look for '2020</a>'
if (false === strpos($item, $this->this_year . '</a>')) {
return false;
}
return true;
}
// Remove the ' 2020' (space + year) string.
function remove_year($item) {
return str_replace(' ' . $this->this_year, '', $item);
}
/**
* Outputs the content for the current Archives widget instance.
*
* @since 2.8.0
*
* @param array $args Display arguments including 'before_title', 'after_title',
* 'before_widget', and 'after_widget'.
* @param array $instance Settings for the current Archives widget instance.
*/
public function widget( $args, $instance ) {
$default_title = __( 'Archives' );
$title = ! empty( $instance['title'] ) ? $instance['title'] : $default_title;
/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
$title = apply_filters( 'widget_title', $title, $instance, $this->id_base );
$remove_year_suffix = ! empty( $instance['remove_year_suffix'] ) ? 1 : 0;
$include_this_year = ! empty( $instance['include_this_year'] ) ? 1 : 0;
echo $args['before_widget'];
if ( $title ) {
echo $args['before_title'] . $title . $args['after_title'];
}
$format = current_theme_supports( 'html5', 'navigation-widgets' ) ? 'html5' : 'xhtml';
/** This filter is documented in wp-includes/widgets/class-wp-nav-menu-widget.php */
$format = apply_filters( 'navigation_widgets_format', $format );
if ( 'html5' === $format ) {
// The title may be filtered: Strip out HTML and make sure the aria-label is never empty.
$title = trim( strip_tags( $title ) );
$aria_label = $title ? $title : $default_title;
echo '<nav role="navigation" aria-label="' . esc_attr( $aria_label ) . '">';
}
// Get links to yearly archives.
$args = array( 'type' => 'yearly', 'echo' => false, 'format' => 'custom', 'before' => '', 'after' => '|' );
$yearly_archives_string = wp_get_archives( $args );
$yearly_archives = array_map( 'trim', explode( '|', $yearly_archives_string ) );
// Get links to monthly archives and remove all that aren't this year.
$args = array( 'type' => 'monthly', 'echo' => false, 'format' => 'custom', 'before' => '', 'after' => '|' );
$monthly_archives_string = wp_get_archives($args);
$monthly_archives = array_filter( array_map('trim', explode('|', $monthly_archives_string)), array( $this, 'archive_exclude_previous_years' ) );
// Optionally remove year from this year's links e.g. "August 2020" -> "August".
if ( $remove_year_suffix ) {
$monthly_archives = array_map( array( $this, 'remove_year' ), $monthly_archives );
}
// If there are any posts this year then insert the links after the year link.
$archives_list = array();
if (count($monthly_archives)) {
// Put this year's month links into a sublist - it breaks the :after css and makes double arrows).
//$archives_list[] = '<li>' . $yearly_archives[0] . '<ul><li>' . implode( '</li><li>', $monthly_archives ) . '</li></ul></li>';
// Put this year's link at top of list.
if ( $include_this_year ) {
$archives_list[] = '<li>' . $yearly_archives[0] . '</li>';
}
// Shift the first element (year) off the list.
array_shift($yearly_archives);
// Add this year's monthly links.
$archives_list[] = '<li>' . implode('</li><li>', $monthly_archives) . '</li>';
}
// Append the other years to this array.
foreach ($yearly_archives as $year_link) {
if (strlen($year_link)) {
$archives_list[] = '<li>' . $year_link . '</li>';
}
}
echo '<ul>' . implode('', $archives_list) . '</ul>';
if ( 'html5' === $format ) {
echo '</nav>';
}
echo $args['after_widget'];
}
/**
* Handles updating settings for the current Archives widget instance.
*
* @since 2.8.0
*
* @param array $new_instance New settings for this instance as input by the user via
* WP_Widget_Archives::form().
* @param array $old_instance Old settings for this instance.
* @return array Updated settings to save.
*/
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$new_instance = wp_parse_args(
(array) $new_instance,
array(
'title' => '',
'remove_year_suffix' => 0,
'include_this_year' => 0,
)
);
$instance['title'] = sanitize_text_field( $new_instance['title'] );
$instance['remove_year_suffix'] = $new_instance['remove_year_suffix'] ? 1 : 0;
$instance['include_this_year'] = $new_instance['include_this_year'] ? 1 : 0;
return $instance;
}
/**
* Outputs the settings form for the Archives widget.
*
* @since 2.8.0
*
* @param array $instance Current settings.
*/
public function form( $instance ) {
$instance = wp_parse_args(
(array) $instance,
array(
'title' => '',
'remove_year_suffix' => 0,
'include_this_year' => 0,
)
);
?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $instance['title'] ); ?>" />
</p>
<p>
<input class="checkbox" type="checkbox"<?php checked( $instance['remove_year_suffix'] ); ?> id="<?php echo $this->get_field_id( 'remove_year_suffix' ); ?>" name="<?php echo $this->get_field_name( 'remove_year_suffix' ); ?>" />
<label for="<?php echo $this->get_field_id( 'remove_year_suffix' ); ?>"><?php _e( 'Remove current year from month links' ); ?></label>
<br/>
<input class="checkbox" type="checkbox"<?php checked( $instance['include_this_year'] ); ?> id="<?php echo $this->get_field_id( 'include_this_year' ); ?>" name="<?php echo $this->get_field_name( 'include_this_year' ); ?>" />
<label for="<?php echo $this->get_field_id( 'include_this_year' ); ?>"><?php _e( 'Include current year at top of list' ); ?></label>
</p>
<?php
}
}
// Load this widget.
add_action( 'widgets_init', 'taw_load_widgets' );
function taw_load_widgets() {
register_widget( 'Truncated_Archives_Widget' );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment