Filter index page plugin

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.

Related posts

Leave a Reply

3 comments

  1. 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… 🙂

  2. 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 }