Different permalink for posts and authors

I would just change the author_base on the global $wp_rewrite object. Also add a field to the Permalink options page, so you can change it at will.

To start: a class to wrap everything up.

<?php
class Custom_Author_Base
{
    const SETTING = 'author_base';

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

    public function _setup()
    {
        // we'll add actions here
    }
}

Now, we can hook into admin init and use the settings API to add a field to the permalink page.

<?php
class Custom_Author_Base
{
    // snip snip

    public function _setup()
    {
        add_action('admin_init', array($this, 'fields'));
    }

    public function fields()
    {
        add_settings_field(
            self::SETTING,
            __('Author Base', 'custom-author-base'),
            array($this, 'field_cb'),
            'permalink',
            'optional',
            array('label_for' => self::SETTING)
        );
    }

    public function field_cb()
    {
        printf(
            '<input type="text" class="regular-text" name="%1$s" id="%1$s" value="https://wordpress.stackexchange.com/questions/77228/%2$s" />',
            esc_attr(self::SETTING),
            esc_attr(get_option(self::SETTING))
        );
    }
}

Unfortunately, the settings API doesn’t actually save anything on the permalink page, so you have to hook into load-options-permalink.php and do your own saving.

<?php
class Custom_Author_Base
{
    // snip snip

    public function _setup()
    {
        add_action('admin_init', array($this, 'fields'));
        add_action('load-options-permalink.php', array($this, 'maybe_save'));
    }

    public function maybe_save()
    {
        if ('POST' !== $_SERVER['REQUEST_METHOD']) {
            return;
        }

        if (!empty($_POST[self::SETTING])) {
            $res = sanitize_title_with_dashes($_POST[self::SETTING]);
            update_option(self::SETTING, $res);
            $this->set_base($res);
        } else {
            delete_option(self::SETTING);
        }
    }
}

Finally, you need to hook into init and set the author base (the set_base method used above).

<?php
class Custom_Author_Base
{
    // snip snip

    public function _setup()
    {
        add_action('init', array($this, 'set_base'));
        add_action('admin_init', array($this, 'fields'));
        add_action('load-options-permalink.php', array($this, 'maybe_save'));
    }

    public function set_base($base=null)
    {
        global $wp_rewrite;

        is_null($base) && $base = get_option(self::SETTING);

        if ($base) {
            $wp_rewrite->author_base = $base;
        }
    }
}

As a plugin.

Leave a Comment