0

I'm trying to create/add a widget to a client's website that lists all non-admin authors and links to their posts. I've been able to do that but one of the authors posts, almost exclusively, using a CPT that I created for recipes so the widget does not link to any of her posts.

Because of this and because it's possible that a similar situation could arise in the future with another CPT I would like my widget to query every post type to see if any given author has published an entry with that post type and then link to an archive page displaying all of there posts, regardless of the post type.

I've searched the codex, various plug-ins, Google searches, etc... but haven't found a solution to this specific issue.

I created a plug-in for this custom widget and am including the code below. As a side note, I'm also having trouble getting the exclude_admin argument to work in the widgets section of the plugin. Any help with that would be appreciated as well. Thanks!

<?php
class HEA_Author_List_Widget extends WP_Widget {

public function __construct() {
    $widget_details = array(
        'classname' => 'hea-author-list',
        'description' => 'A widget to display authors and link to their posts.',
    );

    parent::__construct( 'hea-author-list', 'HEA Author List', $widget_details );

}

public function form( $instance ) {

    // Field Values
    $title      =   ( !empty( $instance['title'] ) ) ? $instance['title'] : '';
    $count      =   ( !empty( $instance['count'] ) ) ? $instance['count'] : 3;
    $orderby    =   ( !empty( $instance['orderby'] ) ) ? $instance['orderby'] : 'post_count';
    $order      =   ( !empty( $instance['order'] ) ) ? $instance['order'] : 'desc';

    // Field Options
    $orderby_options = array(
        'ID'            =>  'ID',
        'email'         =>  'Email',
        'post_count'    =>  'Post Count'
    );

    $order_options = array(
        'desc'  =>  'Descending',
        'asc'   =>  'Ascending'
    );

?>


<div class='unread-posts'>
    <p>
        <label for="<?php echo $this->get_field_name( 'title' ); ?>">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( $title ); ?>" />
    </p>

    <p>
        <label for="<?php echo $this->get_field_name( 'count' ); ?>">Authors To Show: </label>
        <input class="widefat" id="<?php echo $this->get_field_id( 'count' ); ?>" name="<?php echo $this->get_field_name( 'count' ); ?>" type="text" value="<?php echo esc_attr( $count ); ?>" />
    </p>

    <p>
        <label for="<?php echo $this->get_field_name( 'orderby' ); ?>">Order By: </label>
        <select class='widefat'  id="<?php echo $this->get_field_id( 'orderby' ); ?>" name="<?php echo $this->get_field_name( 'orderby' ); ?>">
            <?php foreach( $orderby_options as $value => $name ) : ?>
                <option <?php selected( $orderby, $value ) ?> value='<?php echo $value ?>'><?php echo $name ?></option>
            <?php endforeach ?>
        </select>
    </p>

    <p>
        <label for="<?php echo $this->get_field_name( 'order' ); ?>">Order By: </label>
        <select class='widefat'  id="<?php echo $this->get_field_id( 'order' ); ?>" name="<?php echo $this->get_field_name( 'order' ); ?>">
            <?php foreach( $orderby_options as $value => $name ) : ?>
                <option <?php selected( $order, $value ) ?> value='<?php echo $value ?>'><?php echo $name ?></option>
            <?php endforeach ?>
        </select>
    </p>
</div>


<?php
}


public function widget( $args, $instance ) {

    echo $args['before_widget'];

    if( !empty( $instance['title'] ) ) {
        echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) . $args['after_title'];
    }

    $authors = array(
        'orderby'       =>  $instance['orderby'],
        'order'         =>  $instance['order'],
        'number'        =>  $instance['count'],
        'exclude_admin' =>  true,
        'hide_empty'    =>  false,
        'show_fullname' =>  true,
    );

    $users = wp_list_authors( $authors );

    if( !empty( $users ) || empty( $users ) ) {
        echo '<ul>';
        foreach( $users as $user ) {
            echo '<li>';
            echo the_author_posts_link();
            echo '</li>';
        }
        echo '</ul>';
    }

    echo $args['after_widget'];

}


#public function update( $new_instance, $old_instance ) {}

}

add_action( 'widgets_init', function(){
 register_widget( 'HEA_Author_List_Widget' );
});

?>
0

Looking at the function source on https://developer.wordpress.org/reference/functions/wp_list_authors/ you can see that the post type of post is hard coded into the sql query that returns the authors and post counts.

You could clone the function and add other post types as an argument, but I don't see a more elegant solution sadly.

  • Thanks for your help Andy. As I dug deeper I figured it was going to be messy. In order to clone the function would I just copy/paste the function inside of wp-includes/author-template.php and give it a new name and call that function in the theme or is there a better way of doing that? Thanks again for the help. – Adam Lane Jun 20 '16 at 20:27
  • That's exactly what I'd do. – Andy Macaulay-Brook Jun 20 '16 at 20:28

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.