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 am looking for a wordpress plugin that allows my users to customize which posts are appearing on the home page. The users should have a settings page where they can select which categories and tags they´d like to see posts from.

Do you know if anything like that has been developed? Free or premium.

share|improve this question

3 Answers 3

up vote 1 down vote accepted

I am looking for a wordpress plugin that allows my users to customize which posts are appearing on the home page.

Not sure there's any particular plugins for this, but it's certainly possible with a few functions.

The users should have a settings page where they can select which categories and tags they´d like to see posts from.

Easier than providing a settings page that's seperate from the profile page, i'd actually suggest adding a couple of new fields to the user's profile page, you can call the section home preferences or whatever you like.

Example follows...

Step 1 - Add custom fields to the user profile page

Here i took the same approach as Mike did when answering:
How to add custom form fields to the user profile page, firing on two actions to account for user profile saves and admin user edits.

add_action( 'show_user_profile', 'home_prefs_profile_fields' );
add_action( 'edit_user_profile', 'home_prefs_profile_fields' );

function home_prefs_profile_fields( $user ) { 

    $um = get_user_option( 'taxonomy_selection', $user->ID );
    $tags = ( isset( $um['post_tag'] ) ) ? $um['post_tag'] : array();
    $cats = ( isset( $um['categories'] ) ) ? $um['categories'] : array();
    ?>
    <div id="home-prefs">
    <h3>Home Preferences</h3>
    <table class="form-table">
        <tr>
            <th>
                <label for="tax_input[post_tag]">Tags</label><br />
                <span class="description">Choose which tags you want to display on the home page.</span>
            </th>
            <td>
                <ul id="tag-checklist">
                    <?php wp_terms_checklist( 0, array( 'taxonomy' => 'post_tag', 'selected_cats' => $tags ) ); ?>
                </ul>
                <br class="clear" />
                <hr />
            </td>
        </tr>
        <tr>
            <th>
                <label for="post_category">Categories</label><br />
                <span class="description">Choose which categories you want to display on the home page.</span>
            </th>
            <td>
                <ul id="category-checklist">
                    <?php wp_category_checklist( 0, 0, $cats, false ) ?>
                </ul>
            </td>
        </tr>
    </table>
    </div>
    <?php 
}

Information on the term and category checklists can be found in the source(no docs yet).
http://core.trac.wordpress.org/browser/tags/3.0.2/wp-admin/includes/template.php#L217

Step 2 - Handle saving data on profile/user update

Again, two actions, depending on whether it's a user saving profile changes or another user making changes to another user's profile.

add_action( 'personal_options_update', 'save_home_prefs' );
add_action( 'edit_user_profile_update', 'save_home_prefs' );

function save_home_prefs( $user_id ) {

    if ( !current_user_can( 'edit_user', $user_id ) )
        return false;

    $data = array();

    if( isset( $_POST['tax_input'] ) ) {
        foreach( $_POST['tax_input'] as $taxonomy => $term_ids )
            if( !taxonomy_exists( $taxonomy ) )
                continue;
            else
                $data[$taxonomy] = array_map( 'intval', $term_ids );
    }

    if( isset( $_POST['post_category'] ) )
        $data['categories'] = $_POST['post_category'];

    update_user_meta( $user_id, 'taxonomy_selection', $data );
}

NOTE: It wouldn't hurt to add further sanitization to the above.

Step 3 - Adjust the CSS

Indent children terms, float the main list items, so busy taxonomies don't consume so much height.

add_action( 'admin_print_styles-user-edit.php', 'tax_checklist_css' );
add_action( 'admin_print_styles-profile.php', 'tax_checklist_css' );

function tax_checklist_css() {
    ?>
    <style type="text/css">
        .children { text-indent: 20px }
        #tag-checklist li { float:left;width:30% }
        #category-checklist li { float:left;width:30% }
        #category-checklist li li { float:none;width:auto }
    </style>
    <?php
}

NOTE: 30% width on the list items basically gives you the appearance of 3 columns of terms, you're welcome to adjust the CSS to suit.

This could also just as easily be turned into an enqueue, which will provide some level of caching, inline CSS is quicker to test is all... ;)

Step 4 - Filter home query based on user prefs

Add a filter onto home queries based on user configured settings for tags and categories.

add_action( 'pre_get_posts', 'do_user_post_selection' );

function do_user_post_selection( $query ) {

    if( !is_home() || !is_user_logged_in() )
        return;

    if( isset( $query->query_vars['post_type'] ) && ( 'nav_menu_item' == $query->query_vars['post_type'] ) )
        return; 
    if( 1 < did_action('wp') )
        return;
    global $current_user;

    $tax_selection = get_user_option( 'taxonomy_selection', $current_user->ID );

    if( empty( $tax_selection ) )
        return;

    if( isset( $tax_selection['categories'] ) && ( is_array( $tax_selection['categories'] ) ) && ( !empty( $tax_selection['categories'] ) ) ) 
        $query->set( 'category__in', $tax_selection['categories'] );
    if( isset( $tax_selection['post_tag'] ) && ( is_array( $tax_selection['post_tag'] ) ) && ( !empty( $tax_selection['post_tag'] ) ) ) 
        $query->set( 'tag__in', $tax_selection['post_tag'] );

    return;
}

NOTE: You don't have to use a pre_get_posts filter, you could use parse_query or pass values into a WP_Query object, i personally just find the chosen hook easy to use(and it's what i'm use to using).

UPDATE: Move the home prefs elements to the top of the profile page.

function move_prefs() {
    ?>
    <script type="text/javascript">
        jQuery(document).ready(function($){
            $('#home-prefs').prependTo('#your-profile');
            $('input[type=checkbox]').attr('disabled',false);
        });
    </script>
    <?php
}

add_action( 'admin_head-user-edit.php', 'move_prefs' );
add_action( 'admin_head-profile.php', 'move_prefs' );

NOTE: There's a slight HTML update to the home_prefs_profile_fields function also required, i've updated the function as appropriate in Step 1.

RE: Checkboxes showing disabled from subscribers(see comments). The reason this occurs is due to a capability check in the term checklist functions, these functions are typically used on post creation type screens, so expect the user to have the capability to assign terms to a post(or type), this obviously doesn't apply to this particular case so we can safely remove the disabled attribute from them(jQuery above has been ammended with the appropriate change).

Hope that helps... :)

share|improve this answer
    
Thanks mate. I am getting a parse error. Can you spot it? –  user1635 Dec 13 '10 at 18:54
    
Can you narrow it down to a particular function? All works fine for me(i was testing the code as i went). –  t31os Dec 13 '10 at 21:00
    
The parse error was caused on my part. Excellent code. Exactly what I was looking for. –  user1635 Dec 14 '10 at 15:46
    
Is it possible to make the homepage settings appear first on the profile page? –  user1635 Dec 14 '10 at 15:47
    
There aren't any hooks specifically that will allow the elements to be placed that early, however you could use some jQuery to move them. I'll update my answer with an example for you.. ;) –  t31os Dec 14 '10 at 18:15

Have you looked at Justin Tadlock's Query Posts plugin?

share|improve this answer
    
Thanks a plugin just for admins, right? I´m looking for something that is easy to use for the users of my site. –  user1635 Dec 13 '10 at 14:35
    
What is your site's purpose? You speak of "users" and I assumed you meant WordPress authors, but it sounds like something different. –  ZaMoose Dec 13 '10 at 16:20
    
I´m speaking of regular people using the site. My site is not a blog, but more like twitter. The users should be able to customize what they see on the home page. –  user1635 Dec 13 '10 at 16:55
    
Have you considered BuddyPress? Users can easily customize what shows up in their streams... –  ZaMoose Dec 13 '10 at 16:59

This code is untested, but put it in your function.php file ans see what happends.

In theory this should happen:

  • It adds an extra menu item in the admin interface
  • Adds two meta boxes for categories and tags

In your template, all you have to do is get the values from the meta tags by using this:

$categories = get_option('fp_categories');
$tags = get_option('fp_tags');;

Then use this in you query_post.

This is the plugin / code:

add_action('admin_menu', 'cms_options_menu');


function cms_options_menu() {

    //create new top-level menu
    add_menu_page('CMS options', __('CMS options'), 'administrator', __FILE__, 'cms_options_page',plugins_url('/images/icon.png', __FILE__));
    //call register settings function
    add_action( 'admin_init', 'register_cms_options' );
}


function register_cms_options() {
  //register our settings
  register_setting( 'cms-options', 'fp_categories' );
  register_setting( 'cms-options', 'fp_tags' );
}


function cms_options_page() {
?>
<div class="wrap">
<h2>CMS settings</h2>

<form method="post" action="options.php">
    <?php settings_fields( 'cms-options' ); ?>
    <table class="form-table">
        <tr valign="top">
          <td scope="row"><?php _e('Categories');?></td>
          <td><input type="text" name="fp_categories" class="regular-text" value="<?php echo get_option('fp_categories'); ?>" /></td>
        </tr>
        <tr valign="top">
          <td scope="row"><?php _e('Tags');?></td>
          <td><input type="text" name="fp_tags" class="regular-text" value="<?php echo get_option('fp_tags); ?>" /></td>
        </tr>                       
    </table>

    <div id="fileBrowser" title="File browser"> </div>

    <p class="submit">
    <input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
    </p>

</form>
</div>
<?php }
share|improve this answer
    
Great. I will test it. Thanks! –  user1635 Dec 13 '10 at 11:20
    
Um... I would change the administrator rights in add_menu_page. I think now only admins will see the menu. –  Steven Dec 13 '10 at 11:42
    
It doesn´t save the input in the two fields. When I hit "Save changes", its doesn´t really save. –  user1635 Dec 13 '10 at 16:03
    
That's because the inputs don't have the correct names. –  t31os Dec 14 '10 at 21:48
    
t31os is right. You must change the name of the input fields. See my updated code. –  Steven Dec 15 '10 at 14:09

Your Answer

 
discard

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