Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I want to disable author pages for certain users, for example the admin user doesn't post anything but still has an author page.

Is that possible? Maybe a plugin that adds an option to the users page in the admin panel to enable/disable the author page?

share|improve this question
add comment

4 Answers

up vote 2 down vote accepted

I think a combination of the answers so far along with an admin area field to disable the author archive(s) is the best bet.

A class to wrap everything up (along with some constants and methods that will be clear later):

<?php
class Author_Archive_Disabler
{
    // meta key that will store the disabled status
    const KEY = '_author_archive_disabled';

    // nonce name
    const NONCE = 'author_archive_nonce';

    private static $ins = null;

    public static function instance()
    {
        is_null(self::$ins) && self::$ins = new self;
        return self::$ins;
    }

    public static function init()
    {
        add_action('plugins_loaded', array(self::instance(), '_setup'));
    }

    // helper to see if the archive is disabled.
    public static function is_disabled($user_id)
    {
        return 'on' == get_user_meta($user_id, self::KEY, true);
    }

    // adds actions and such
    public function _setup()
    {
        //
    }
}

To add fields you hook into edit_user_profile (shows fields on profiles other than your own) and show_user_profile (shows fields on your own profile).

<?php
class Author_Archive_Disabler
{
    // snip snip

    // adds actions and such
    public function _setup()
    {
        add_action('edit_user_profile', array($this, 'field'));
        add_action('show_user_profile', array($this, 'field'));
    }

    public function field($user)
    {
        // only let admins do this.
        if(!current_user_can('manage_options'))
            return;

        echo '<h4>', __('Disable Archive', 'author-archive-disabler'), '</h4>';

        wp_nonce_field(self::NONCE . $user->ID, self::NONCE, false);

        printf(
            '<label for="%1$s"><input type="checkbox" name="%1$s" id="%1$s" value="on" %2$s /> %3$s</label>',
            esc_attr(self::KEY),
            checked(get_user_meta($user->ID, self::KEY, true), 'on', false),
            __('Disable Author Archive', 'author-archive-disabler')
        );
    }
}

Pretty straight forward: only show the field to administrators, print a header, nonce field and the "disable" checkbox itself.

You hook into edit_user_profile_update (others' profiles) and personal_options_update (your own profile) to save things.

<?php
class Author_Archive_Disabler
{
    // snip snip

    // adds actions and such
    public function _setup()
    {
        add_action('edit_user_profile', array($this, 'field'));
        add_action('show_user_profile', array($this, 'field'));
        add_action('edit_user_profile_update', array($this, 'save'));
        add_action('personal_options_update', array($this, 'save'));
    }

    // snip snip

    public function save($user_id)
    {
        if(
            !isset($_POST[self::NONCE]) ||
            !wp_verify_nonce($_POST[self::NONCE], self::NONCE . $user_id)
        ) return; // nonce is no good, bail

        if(!current_user_can('edit_user', $user_id))
            return; // current user can't edit this user, bail

        update_user_meta($user_id, self::KEY,
            !empty($_POST[self::KEY]) ? 'on' : 'off');
    }
}

Verify the nonce, make sure current user can actually edit the user, then save stuff. if the box is checked, it will go in as "on".

Now hook into template_redirect, check for the author page and 404 it if it's disabled.

<?php
class Author_Archive_Disabler
{
    // snip snip

    // adds actions and such
    public function _setup()
    {
        add_action('edit_user_profile', array($this, 'field'));
        add_action('show_user_profile', array($this, 'field'));
        add_action('edit_user_profile_update', array($this, 'save'));
        add_action('personal_options_update', array($this, 'save'));
        add_action('template_redirect', array($this, 'maybe_disable'));
    }

    // snip snip

    public function maybe_disable()
    {
        global $wp_query;

        // not an author archive? bail.
        if(!is_author())
            return;

        if(self::is_disabled(get_queried_object_id()))
        {
            $wp_query->set_404();
        }
    }
}

You can also filter the author link so a disabled user never gets linked to.

<?php
class Author_Archive_Disabler
{
    // snip snip

    // adds actions and such
    public function _setup()
    {
        add_action('edit_user_profile', array($this, 'field'));
        add_action('show_user_profile', array($this, 'field'));
        add_action('edit_user_profile_update', array($this, 'save'));
        add_action('personal_options_update', array($this, 'save'));
        add_action('template_redirect', array($this, 'maybe_disable'));
        add_filter('author_link', array($this, 'change_link'), 10, 2);
    }

    // snip snip

    public function change_link($link, $author_id)
    {
        if(self::is_disabled($author_id))
            return apply_filters('author_archive_disabler_default_url', home_url(), $author_id);

        return $link;
    }
}

All of the above as a plugin

share|improve this answer
1  
"I think a combination of the answers" -- I agree –  s_ha_dum Dec 4 '12 at 16:40
    
Thanks, I have installed this. Did you submit this to the official plugin repository? –  Jan-Philip Gehrcke Jan 17 at 14:55
add comment

Altering the author links as suggested in other answers is certainly part of the solution. You don't want to be printing those links if you aren't using them. If you want to be sure to kill the author pages though...

function tst() {
  global $wp_query;
  if (is_author() && !empty($wp_query->query['author_name'])) {
    $author = get_user_by('login',$wp_query->query['author_name']);
    if ( 1 === $author->ID) {
      wp_safe_redirect(get_bloginfo('url'),'301'); // or whatever you want
    }
  }
}
add_action('template_redirect','tst');
share|improve this answer
    
Returning false on the get_author_posts_link filter will prevent the link from being printed. :) –  Chip Bennett Dec 4 '12 at 15:12
    
I think you misread me. Yes, it should prevent the link from being printed, which is why I started by saying that those answers are "certainly part of the solution", but an author's page would still be accessible if typed directly into the URL bar. It isn't that hard to work out the URL structure of an author's page. This stops that workaround. It is a hard block on an author's page, in case someone gets clever. –  s_ha_dum Dec 4 '12 at 15:22
    
So all in all the only option I have is to manually implement(extend) a filter for every author? Not really satisfying but if it's the only option I'll have to do it. Maybe I'll write a plugin for that :) –  Stephan S. Dec 4 '12 at 15:26
    
Well, no. I wouldn't do it manually. I would put together a plugin with 'block author' check-boxes or something. You could block by 'role' or 'capability' if you wanted. That might save some effort. –  s_ha_dum Dec 4 '12 at 15:31
    
That's what I'm planning to do but thank you for the recommendation :) –  Stephan S. Dec 4 '12 at 16:25
show 2 more comments

I would recommend filtering author_link, which filters the returned output of get_author_posts_url():

$link = apply_filters('author_link', $link, $author_id, $author_nicename);

Filter like so:

function wpse74924_filter_author_link( $link, $author_id, $author_nicename ) {

    if ( user_can( $author_id, 'administrator' ) ) {
        // This is an administrator
        return '';
        // You could also return home_url() to link to the site front page
    }
    // Otherwise, return $link unmodified
    return $link;
}
add_filter( 'author_link', 'wpse74924_filter_author_link' );

Or, perhaps even cleaner, filter the_author_posts_link, which filters the returned output of the_author_posts_link()`:

echo apply_filters( 'the_author_posts_link', $link );

So, say, for example, you didn't want to display an author archive index for administrator users, you could do something like so:

function wpse74924_filter_the_author_posts_link( $link ) {
    // Since $author_id doesn't get passed to this filter,
    // we need to query it ourselves
    $author_id = get_the_author_meta( 'ID' );

    if ( user_can( $author_id, 'administrator' ) ) {
        // This is an administrator
        __return_false();
    }
    // Otherwise, return $link unmodified
    return $link;
}
add_filter( 'the_author_posts_link', 'wpse74924_filter_the_author_posts_link' );
share|improve this answer
    
(You are missing a parenthesis in your if line but that isn't the problem.) I was puzzled by your solution at first because Twenty Eleven on 3.4.1 still prints working author URLs. In fact, I couldn't get the the_author_posts_link hook to fire at all. After some chasing it around, I stuck the_author_posts_links() in single.php and the hook fired. I got an error about missing argument 2 for wpse74924_* but the hook fired. Apparently Twenty Eleven on 3.4.1 doesn't use a function that calls that hook. ... cautionary tale I guess. –  s_ha_dum Dec 4 '12 at 15:40
    
Syntax error fixed. Also, fixed arguments passed to the callback. author_link accepts 3 arguments, but the_author_posts_link only accepts one. Also, the reason that you couldn't get the filter to fire in Twenty Eleven is because Twenty Eleven uses get_author_posts_url() (the first filter referenced in the answer) instead of get_author_posts_link(). I've added an example callback for this filter. –  Chip Bennett Dec 4 '12 at 15:58
    
Well, somebody edited my answer while I was editing it, and it got rolled back. :/ Just a sec; let me fix. –  Chip Bennett Dec 4 '12 at 15:59
1  
+1 If you're already using __return_false(), then you can also use __return_empty() instead of return '';. –  kaiser Dec 4 '12 at 16:16
    
True, @kaiser. I really just left the empty string there, as a placeholder for a more likely return value, like home_url() (see the inline comments). –  Chip Bennett Dec 4 '12 at 16:19
add comment

you could detect the author name on the template_redirect hook and redirect to the home page

http://codex.wordpress.org/Author_Templates#Setting_Up_for_Author_Information

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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