0

I've got a cpt called 'blog', now I would like to list all authors that contributed to that cpt. Also I would like to list all blogposts (from the 'blog' cpt) grouped in months, like wp_get_archives() does.

  1. Authors. I tried to use wp_list_authors but it only lists authors from regular posts, not cpt's. I only want list authors of the 'blog' cpt. What to do?

  2. Monthly archives. I tried to use wp_list_archives() following instructions from Bainternet (here: Get monthly archives for custom post type) and that lists "monthname year", looks great. BUT, the permalinks created looks like this: www.example.com/2011/10
    ...and that leads nowhere! I get a 404 error. All the 'blog' cpt posts are located under www.example.com/blog and I want the date archive url to include /blog as well. So maybe it's just a rewrite thing but I do fix that? Just manually typing www.example.com/blog/2011/10 only gets me to the 404 error page also.

Hope you can help me!


Update 1

I managed to rewrite the urls to the archives so now they look like this: www.example.com/blog/2011/10

This is the code I used for the rewrite:

add_rewrite_tag('%blog-date%','([\d]{4}-[\d]{2}-[\d]{2})');

add_action( 'init', 'blog_rewrites' );
function blog_rewrites() {
    add_rewrite_rule( "blog/day/([\d]{4}-[\d]{2}-[\d]{2})/?$", 'index.php?post_type=blog&blog-date=$matches[1]', 'top' );
}

add_filter( 'query_vars', 'blog_vars' );
function blog_vars ( $vars ) {
    $vars[] = 'blog-date';
    return $vars;
}

But I still get the 404 error though...


Update 2

Applying code from @Bainternet's response below I was able to get my authors list functioning but I still get a 404 on my monthly archives links. The url seems correct though: www.example.com/blogg/2011/10 This is the code from my functions.php right now:

add_filter('get_archives_link', 'blog_archive_links');
function blog_archive_links($html){
    $home_url = home_url();
    $home_url_with_blog  = $home_url .'/blogg';
    return str_replace($home_url,$home_url_with_blog,$html);
}

//to match http://www.example.com/blog/2011/12/1/ use
add_rewrite_rule('^blogg/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$','index.php?post_type=blogg&year=$matches[1]&monthnum=$matches[2]&day=$matches[3]','top');
//to match http://www.example.com/blog/2011/12/1/page/2 use
add_rewrite_rule('^blogg/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/page/?([0-9]{1,})/?$','index.php?post_type=blogg&year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&page=$matches[4]','top');
//to match http://www.example.com/blog/2011/12/ use
add_rewrite_rule('^blogg/([0-9]{4})/([0-9]{1,2})/(?$','index.php?post_type=blogg&year=$matches[1]&monthnum=$matches[2]','top');
//to match http://www.example.com/blog/2011/12/page/2 use
add_rewrite_rule('^blogg/([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$','index.php?post_type=blogg&year=$matches[1]&monthnum=$matches[2]&page=$matches[3]','top');

function Cpt_getarchives_where_filter( $where , $r ) {
  $post_type = 'blogg';
  return str_replace( "post_type = 'post'" , "post_type = '$post_type'" , $where );
}

And this is the code in my sidebar.php:

add_filter( 'getarchives_where' , 'Cpt_getarchives_where_filter' , 10 , 2 );
wp_get_archives();
remove_filter('getarchives_where' , 'Cpt_getarchives_where_filter' , 10 );

As you can see my cpt isn't called 'blog', it's actually called 'blogg', that's the Swedish spelling, shouldn't matter though. Also, I'm not using any plugin to get the cpt archives to work, I've simply created a file called archive-blogg.php and set the permalinks for the blogposts in the 'blogg' cpt to '/blogg' using a plugin called 'Custom Post Permalinks' that doesn't seem to be around anymore. It seems to do everything else right but I could try to replace that plugin with some code in functions.php.

Apart from that, anything else that could be tested to get this to work?

1 Answer 1

1

This should have been two different questions but anyway,

I needed to use wp_list_authors for custom post type so i created this function:

function get_authors_ids_by_post_type($type = null,$args = ''){
    if ($type === null) return;
    global $wpdb;
    $defaults = array(
        'orderby' => 'name', 'order' => 'ASC', 'number' => '',
        'optioncount' => false, 'exclude_admin' => true,
        'show_fullname' => false, 'hide_empty' => true,
        'feed' => '', 'feed_image' => '', 'feed_type' => '', 'echo' => true,
        'style' => 'list', 'html' => true
    );

    $args = wp_parse_args( $args, $defaults );
    extract( $args, EXTR_SKIP );

    $return = '';

    $query_args = wp_array_slice_assoc( $args, array( 'orderby', 'order', 'number' ) );
    $query_args['fields'] = 'ids';
    $authors = get_users( $query_args );
    $author_count = array();
    foreach ( (array) $wpdb->get_results("SELECT DISTINCT post_author, COUNT(ID) AS count FROM $wpdb->posts WHERE post_type = '$type' AND " . get_private_posts_cap_sql( $type ) . " GROUP BY post_author") as $row )
        $author_count[$row->post_author] = $row->count;
        foreach ( $authors as $author_id ) {
            $author = get_userdata( $author_id );

            if ( $exclude_admin && 'admin' == $author->display_name )
                continue;

            $posts = isset( $author_count[$author->ID] ) ? $author_count[$author->ID] : 0;

            if ( !$posts && $hide_empty )
                continue;

            $link = '';

            if ( $show_fullname && $author->first_name && $author->last_name )
                $name = "$author->first_name $author->last_name";
            else
                $name = $author->display_name;

            if ( !$html ) {
                $return .= $name . ', ';

                continue; // No need to go further to process HTML.
            }

            if ( 'list' == $style ) {
                $return .= '<li>';
            }

            $link = '<a href="' . get_author_posts_url( $author->ID, $author->user_nicename ) . '" title="' . esc_attr( sprintf(__("Posts by %s"), $author->display_name) ) . '">' . $name . '</a>';

            if ( !empty( $feed_image ) || !empty( $feed ) ) {
                $link .= ' ';
                if ( empty( $feed_image ) ) {
                    $link .= '(';
                }

                $link .= '<a href="' . get_author_feed_link( $author->ID ) . '"';
                $alt = $title = '';
                if ( !empty( $feed ) ) {
                    $title = ' title="' . esc_attr( $feed ) . '"';
                    $alt = ' alt="' . esc_attr( $feed ) . '"';
                    $name = $feed;
                    $link .= $title;
                }

                $link .= '>';

                if ( !empty( $feed_image ) )
                        $link .= '<img src="' . esc_url( $feed_image ) . '" style="border: none;"' . $alt . $title . ' />';
                else
                    $link .= $name;

                $link .= '</a>';

                if ( empty( $feed_image ) )
                    $link .= ')';
            }

            if ( $optioncount )
                $link .= ' ('. $posts . ')';

            $return .= $link;

            $return .= ( 'list' == $style ) ? '</li>' : ', ';

        }

        $return = rtrim($return, ', ');

        if ( !$echo )
            return $return;

        echo $return;
}

which is the same as wp_list_authors but you can also define the post type.

as for the date based archive you get a 404 because your rewrite is wrong, mainly because of the way the links are generated and secondly because of your rewrite rule which uses blog-date and that is not defined anywhere in the query itself.

to get your desired permalink working you need to use another hooked function :

add_filter('get_archives_link', 'blog_archive_links');

function blog_archive_links($html){
    $home_url = home_url();
    $home_url_with_blog  = $home_url .'blog/';
    return str_replace($home_url,$home_url_with_blog,$html);
}

this should set the links so all that is left is to make them work :)

So your rewrite rules should look something like this:

//to match http://www.example.com/blog/2011/12/1/ use
add_rewrite_rule('^blog/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$','index.php?post_type=blog&year=$matches[1]&monthnum=$matches[2]&day=$matches[3]','top');

//to match http://www.example.com/blog/2011/12/1/page/2 use
add_rewrite_rule('^blog/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/page/?([0-9]{1,})/?$','index.php?post_type=blog&year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&page=$matches[4]','top');

//to match http://www.example.com/blog/2011/12/ use
add_rewrite_rule('^blog/([0-9]{4})/([0-9]{1,2})/(?$','index.php?post_type=blog&year=$matches[1]&monthnum=$matches[2]','top');

//to match http://www.example.com/blog/2011/12/page/2 use
add_rewrite_rule('^blog/([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$','index.php?post_type=blog&year=$matches[1]&monthnum=$matches[2]&page=$matches[3]','top');
1
  • Wow that's really helpful, thanks a bunch! I got the authors list to work but I still get a 404 on my monthly archives links. Please check out 'Update 2' on my original post, thanks.
    – Richard B
    Commented Oct 5, 2011 at 9:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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