1

I am trying to outline a new project where I want to give my users the ability to customize their 'profile' pages in my website theme. Concepts like adding in their own background images, choosing templates etc.

It seemed logical to me to store this information in the author meta, as that seems to be the only table that stores unique information for each user. Once I have input boxes setup then I can easily make the calls in my theme.

Users don't appear to be post-types, or taxonomies, but I can't figure out what they 'really' are. Could someone take a moment to describe what 'users' really are in the eyes of WordPress?

What I was ultimately hoping for is to find a class where I can easily add metaboxes to the edit author profile pages.

I do know how to extend profile fields via forms, but I am looking for something much more flexible.

*I use the farinspace metabox class for my post-types and absolutely love how it works, really hoping I can use something similar for the author pages..

Is any of this possible, or is there a better route I should take?

1
  • that wont work since farinspace metabox class save function works with save_post hook. So the most flexible solution you have here is to add the fields yourself
    – Bainternet
    Commented Jun 30, 2011 at 12:09

2 Answers 2

2

Authors are rather simple content objects in WordPress. They have roles and capabilities, some basic meta data and their own edit screens. That’s it pretty much. If you want to add a custom taxonomy to authors you have to mirror each user with a (hidden) custom post type because the author object doesn’t support taxonomies …

Anyway … for meta boxes I have written a simple class. I hope it helps to understand how things work and where to hook in.

class T5_User_Profile_Addon

<?php
/**
 * Adds a form field to the edit profile page.
 *
 * @author Thomas Scholz http://toscho.de
 * @version 1.2
 * @license GPL
 *
 */
class T5_User_Profile_Addon
{

    public $settings = array (
    /* The name attribute. */
        'name'        => ''
    ,   'label'       => ''
    ,   'description' => ''

    /* You may use the following placeholder:
     * %name%        - name attribute
     * %label%       - label text
     * %description% - additional text
     * To use more placeholders, extend markup_filter().
     */
    ,   'markup'      => ''
    /* If both are not FALSE, they will replace the 'markup', and a
     * table will be created. Uses the same placeholders as 'markup'.
     */
    ,   'th'          => FALSE
    ,   'td'          => FALSE
    /* Capabilities to show and edit the field.
     * Useful, if want to add a field that only administrators or editors
     * may edit or view.
     */
    ,   'cap_show'    => 'read'
    ,   'cap_save'    => 'edit_user'
    );

    /**
     * Constructor
     *
     * @param array $args See settings. 'name' and 'markup' required.
     */
    public function __construct( $args )
    {
        $this->settings = array_merge( $this->settings, $args );

        // The id attribute should be different to name, otherwise it doesn’t
        // work in Opera.
        empty ( $this->settings['id'] )
            and $this->settings['id'] = $this->settings['name'] . '_id';

        FALSE !== $this->settings['th'] and FALSE !== $this->settings['td']
            and $this->settings['markup'] = '<table class="form-table"><tr><th>'
                . $this->settings['th'] . '</th><td>' . $this->settings['td']
                . '</td></tr></table>';

        add_action( 'show_user_profile',        array ( $this, 'show' ) );
        add_action( 'edit_user_profile',        array ( $this, 'show' ) );
        add_action( 'personal_options_update',  array ( $this, 'save' ) );
        add_action( 'edit_user_profile_update', array ( $this, 'save' ) );
    }

    /**
     * Prints the form.
     *
     * @param  object $user
     * @return void
     */
    public function show( $user )
    {
        if ( ! current_user_can( $this->settings['cap_show'], $user->ID ) )
        {
            return;
        }

        $label   = "<label for='{$this->settings['id']}'>{$this->settings['label']}</label>";
        $markup  = strtr( $this->settings['markup'],
            array (
                '%name%'        => $this->settings['name']
            ,   '%id%'          => $this->settings['id']
            ,   '%label%'       => $label
            ,   '%description%' => $this->settings['description']
            )
        );
        $old_val = trim( get_the_author_meta( $this->settings['name'], $user->ID ) );
        $markup  = $this->markup_filter( $markup, $old_val );

        print $markup;
    }

    /**
     * Saves the data.
     *
     * @param  int $user_id
     * @return void
     */
    public function save( $user_id )
    {
        if ( ! current_user_can( $this->settings['cap_save'], $user_id ) )
        {
            return;
        }

        $input = empty ( $_POST[ $this->settings['name'] ] )
            ? '' : $_POST[ $this->settings['name'] ];
        $input = $this->prepare_input( $input );

        update_user_meta( $user_id, $this->settings['name'], $input );
    }

    /**
     * Prepares the user input. For extensions.
     *
     * @param  string $input
     * @return string
     */
    public function prepare_input( $input )
    {
        return $input;
    }

    /**
     * Prepares the form markup.
     *
     * @param  string $markup
     * @param  string $old_val
     * @return string
     */
    public function markup_filter( $markup, $old_val )
    {
        $old_val = htmlspecialchars( $old_val, ENT_QUOTES, 'utf-8', FALSE );
        return str_replace( '%content%', $old_val, $markup );
    }
}

Usage

<?php
add_action( 'init', 'init_profile_addons' );
function init_profile_addons()
{
    $GLOBALS['extended_author_text'] = new T5_User_Profile_Addon(
        array (
            'name' => 'extended_author_text'
        ,   'label' => 'Second text field'
        ,   'description' => '<p>This text will be shown at the top of your author archive. You may use HTML.</p>'
        ,   'markup' => '<table class="form-table"><tr><th>%label%<br /><br />%description%</th>
            <td><textarea name="%name%" id="%id%" rows="10" cols="30">%content%</textarea></td></tr></table>'
        )
    );
}

Example: a checkbox

In some cases you may want to extend the class to change some behavior. Here I built a checkbox:

/**
 * Template for a simple checkbox.
 */
class T5_User_Profile_Checkbox extends T5_User_Profile_Addon
{
    public function prepare_input( $input )
    {   // Convert the checkbox value to integer
        return '' == trim( $input ) ? 0 : 1;
    }

    public function markup_filter( $markup, $old_value )
    {   // Preselect the checkbox if necessary.
        $checked = 1 == $old_value ? ' checked="checked"' : '';
        return str_replace( '%checked%', $checked, $markup );
    }
}

My primitive template system may not be the best approach. There is no user friendly error handling. I just needed something that works and is easy to understand. :)

2
  • Wow this is a great start, thank you! By any chance have you modified this in the past to add the ability to add in a file uploader? If not, I'll see if I can't work one out myself. I like the idea of mirroring to a post-type. Maybe Scribu's plugin can be modified for this as it does not pick up authors as a post type. I'll fire him over a quick question on that idea
    – shawn
    Commented Jul 31, 2011 at 9:44
  • I posted some code for a file upload earlier. It shouldn’t be so hard to combine both.
    – fuxia
    Commented Jul 31, 2011 at 10:32
1

/wp-admin/user-edit.php: do_action( 'show_user_profile', $profileuser );. Try hooking your call to the metabox there. If it doesn't work, you should take a look on which scripts get added for post edit screens and add them there too.

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.