Site icon Code Solution

Disable author pages for specific users

The question:

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?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

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

Method 2

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');

Method 3

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' );

Method 4

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


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Exit mobile version