4

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?

4 Answers 4

6

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

3
  • 1
    "I think a combination of the answers" -- I agree
    – s_ha_dum
    Commented Dec 4, 2012 at 16:40
  • Thanks, I have installed this. Did you submit this to the official plugin repository? Commented Jan 17, 2014 at 14:55
  • chrisguitarguy plugin is great but if you have alot of users it is a nightmare going through each user is there away to modify the script in bulk at all? I want to archive all people with the role "Buyer" but I want keep public all users with the role "Agent" public. Commented Jul 14, 2022 at 13:12
1

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');
6
  • Returning false on the get_author_posts_link filter will prevent the link from being printed. :) Commented Dec 4, 2012 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
    Commented Dec 4, 2012 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.
    Commented Dec 4, 2012 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
    Commented Dec 4, 2012 at 15:31
  • That's what I'm planning to do but thank you for the recommendation :)
    – Stephan S.
    Commented Dec 4, 2012 at 16:25
1

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' );
5
  • (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
    Commented Dec 4, 2012 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. Commented Dec 4, 2012 at 15:58
  • Well, somebody edited my answer while I was editing it, and it got rolled back. :/ Just a sec; let me fix. Commented Dec 4, 2012 at 15:59
  • 1
    +1 If you're already using __return_false(), then you can also use __return_empty() instead of return '';.
    – kaiser
    Commented Dec 4, 2012 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). Commented Dec 4, 2012 at 16:19
0

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

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.