Question

This has been resolved, thanks to user 'stink', see the original question below and my observations - scrolling past to the selected answer won't make any sense

Original Question

Writing a custom post type plugin for wordpress and am seriously stuck here.

I have everything working as it should be in the admin side now but in the front end I can only get pages like /type/title to render.

What I really want is a list of posts associated to a specific author via a url like /type/author/AUTHORNAME (e.g. /games/author/myuser).

I have setup a rewrite rule:

public static function rewrite_rules(&$wpr) {
    $key = self::$postType.'/author/(.+)';
    $rewrite = 'index.php?author=$matches[1]&post_type=$matches[2]';
    $newRules = Array($key => $rewrite);
    $wpr->rules = $newRules + $wpr->rules;
    //echo "<pre>"; print_r($wpr->rules);
    //flush_rewrite_rules();
}

    add_filter('generate_rewrite_rules', array(get_class(), 'rewrite_rules'));

(rest of class not shown)

And I thought that it was as simple as adding into the template_include filter.

If you try to access /type/author/AUTHORNAME, WP lands you at archive.php

public static function template_include($path) {
    if (get_post_type() == self::$postType) {
        if (is_single()) {
            if ($theme_file = locate_template(array('single-gamesdb.php'))) {
                $path = $theme_file;
            } else {
                $path = RGPDB_ROOT.'/templates/single-gamesdb.php';
            }
        } elseif (is_author()) {
            echo "!!!"; exit;
            if ($theme_file = locate_template(array('author-gamesdb.php'))) {
                $path = $theme_file;
            } else {
                $path = RGPDB_ROOT.'/templates/author-gamesdb.php';
            }
        } elseif (is_archive()) {
                $path = RGPDB_ROOT.'/templates/author-gamesdb.php';
        }
    } else {
        if (is_archive()) {
            $type = get_query_var('post_type');
            echo "!!!! $type";
        }
    }
    //echo $path;
    return $path;

}

The first bit of template_include works - /games/some-game-title accesses single-gamesdb.php and renders just fine.

WP will get to the lower section where if (is_archive()) { ... } is on its own but I can't now figure out what post type I have from the query string. Examining the query_vars filter shows that post_type= and author= are perfectly valid, however, this is being recognised as an archive page rather than an author.

Am I missing something about setting up the custom post type as I thought you could attach an author page directly to them.

Solution

What I found was that I didn't have the register_post_types() call configured completely right, i'd advise using the link that stink provides lower down to assist building the PHP to get you going, however, there are a couple of gotcha's.

If you want a custom permalink which I did which displays posts from your custom post type only for a given user and you want to segregate the design as in the proper pattern then you need to do 2 additional steps:

1) You will still need to add a custom rewrite which is fairly easy:

function my_rewrite_rules(&$wpr) {
    $key = 'mypostype/author/([a-zA-Z0-9]+)';
    $rewrite = 'index.php?post_type=myposttype&author_name=$matches[1]';
    $newRules = Array($key => $rewrite);
    $wpr->rules = $newRules + $wpr->rules;
}
    add_filter('generate_rewrite_rules', 'my_rewrite_rules);

$wpr above is just me shortening $wp_rewrite but remember it is passed by reference so you need the & on the beginning

2) If you just wanted to hack into your theme's author.php file to add your custom design you could do that - post_type is already a registered variable as is author_name - you can simply add some logic there. If you want to have a completely separate page like I needed for a few reasons then you will need to add into the template_include hook.

function my_template_include($path) {
    if (get_post_type() == 'myposttype') {
            if (is_author()) {
        if ($theme_file = locate_template(array('author-myposttype.php','author.php'))) {
        $path = $theme_file;
        } else {
        $path = plugin_dir_path(__FILE__).'/templates/author-gamesdb.php';
        }
            }
         }
    }
    add_filter('template_include', 'my_template_include');

The locate_template() call will search the child theme, theme etc in the standard hierarchy to try to find one of those files in the array (e.g. author-myposttype.php and author.php).

The Gotcha

If you do not have any posts assigned to the user you want to get an author page for you will not get presented with your custom author page or the base one, you will, for some reason, end up in archive.php

Eg: http://mywebsite.com/myposttype/author/someauthorname

With posts assigned to the author 'someauthorname' for this custom post type will land you in author-myposttype.php or author.php but if you have no posts authored by that person you won't end up there.

Remember that when setting up known variables in your rewrite, a WP_Query object will be automatically created for you with most of the parameters and you can simply do the standard loop

if (have_posts()) {
    while (have_posts()) {
        the_post();
        ..... your display code ....
    }
}

I am no fan of the short syntax WP uses by default with colons and endwhile/endif

Was it helpful?

Solution

What you need is the is author Conditional Tag.

This Conditional Tag checks if an Author archive page is being displayed. This is a boolean function, meaning it returns either TRUE or FALSE.

Add the conditional to single.php. If you want you can add another loop to the same file or if the conditional is met switch to custom-single.php

Edit: This is a great site to generate code for custom post types.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top