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'm looking for a way to set the default "View" options under post types in the admin area. For example, by default Posts will default to a "list" view instead of "excerpt" - I'd like to change this to excerpt by default - what would be the best way to achieve this? I've done a bit of searching on this, but am stuck in the mud thus-far. Any help would be greatly appreciated. Thanks!

share|improve this question
add comment

3 Answers

up vote 8 down vote accepted
+50

Although having the feature of persistent settings in core is nice, it may take quite a while before it's actually accepted. WordPress 3.5 is still quite far away.

So let's augment the global $_REQUEST array instead.

add_action( 'load-edit.php', 'wpse34956_force_excerpt' );
function wpse34956_force_excerpt() {
    $_REQUEST['mode'] = 'excerpt';
}

This will lock up modes, forcing excerpt mode all the time, so let's turn let the user decide but keep it persistent using the user's metadata:

add_action( 'load-edit.php', 'wpse34956_persistent_posts_list_mode' );
function wpse34956_persistent_posts_list_mode() {
    if ( isset( $_REQUEST['mode'] ) ) {
        // save the list mode
        update_user_meta( get_current_user_id(), 'posts_list_mode', $_REQUEST['mode'] );
        return;
    }
    // retrieve the list mode
    if ( $mode = get_user_meta( get_current_user_id(), 'posts_list_mode', true ) )
        $_REQUEST['mode'] = $mode;
}

You can further interpolate post_type into all by taking into account the $_GET['post_type'] variable when available.

add_action( 'load-edit.php', 'wpse34956_persistent_posts_list_mode' );
function wpse34956_persistent_posts_list_mode() {

    // take into account post types that support excerpts
    $post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : '';
    if ( $post_type && !post_type_supports( $post_type, 'excerpt' ) )
        return; // don't care

    if ( isset( $_REQUEST['mode'] ) ) {
        // save the list mode
        update_user_meta( get_current_user_id(), 'posts_list_mode' . $post_type, $_REQUEST['mode'] );
        return;
    }

    // retrieve the list mode
    if ( $mode = get_user_meta( get_current_user_id(), 'posts_list_mode' . $post_type, true ) )
        $_REQUEST['mode'] = $mode;
}

Viola! Persistent list mode per post type per user, no hacks.

share|improve this answer
    
Good solution. Got a much easier one shortly after I put a bounty on this! But, since you have the solution, I'll give you the bounty, although I think I'll incorporate your way instead as that is actually persistent rather than like the default behaviour except with excerpt instead of list. Edit, can award it in 17 hours so bear with me! –  Hosh Sadiq Mar 30 '12 at 21:39
    
Thank you, glad to have been of help. A very interesting question. –  soulseekah Mar 30 '12 at 21:58
add comment

Okay, so shortly after I put a bounty up, I came up with the following solution. It is the default behaviour in every way, except that it selects excerpt view for whatever post type you want (instead of the default list view).

<?php

add_action( 'admin_init', 'my_admin_init' ); // initiate admin hook

function my_admin_init() {
    // if mode is not set redirect to a default mode.
    if(!isset($_GET['mode'])) {
        if('forms' == $_GET['post_type'] || 'client-quotes' == $_GET['post_type'] ) {
            wp_redirect( admin_url( 'edit.php?mode=excerpt&' . http_build_query( $_GET ) ) );
            exit;
        }
    }
}

?>

NOTE: I recommend Soulseekah's approach, if you don't want it to remember the user's choice, you can incorporate my code with his code a bit. NOTE 2: If/when EAMann's patch is part of the core, obviously his method would be the best one as it wouldn't require you to go the long way round. I just don't like it at the moment as you have to edit the core files.

share|improve this answer
1  
This makes sense. However, paged is not taken into account (pagination) + using wp_redirect instead of raw headers would might be a little "cleaner", and I'm not sure how efficient redirection is. Other than that looks interesting. Also, $_GET['post_type'] might not be set, resulting in a warning if errors are turned on. +1 for the effort and the patience. Didn't realize the question was so old. –  soulseekah Mar 30 '12 at 22:03
2  
My problem with this approach is that it involves a redirect. So you're loading WP not once, but twice just to get to the post listing page. –  EAMann Mar 30 '12 at 22:36
    
@Soulseekah, you're right, didn't think that through, I've updated the code to take into account all $_GET variables. As for the $_GET['post_type'], honestly, I wasn't too bothered with that as I only required it to be for a custom post type, which would always be there. Obviously this can be omitted. @EAMann, You are right, however, this was the best solution I could come up with. I tried manually setting $_GET parameters, hoping that it would be set BEFORE it was read, but this didn't seem to be to the case. –  Hosh Sadiq Mar 30 '12 at 23:27
add comment

The post view screen switches from list view to excerpt view based on the value of the "mode" parameter in the query string. If the "mode" parameter is not set, then WordPress defaults to list view.

Unfortunately, this parameter is not filterable, so there's no easy way to control it programatically.

So I'm going to do something I never do ... I'm going to tell you how to hack Core to make this work ...

Adding a filter

Open /wp-admin/includes/class-wp-posts-list-table.php and find the prepare_items() method (around line 81).

On line 99, WordPress checks to see whether or not the "mode" parameter was set in the request and uses this to set the global $mode variable:

$mode = empty( $_REQUEST['mode'] ) ? 'list' : $_REQUEST['mode'];

We're going to change this line to filter the default setting. Change this line to:

$mode = empty( $_REQUEST['mode'] ) ? apply_filters( 'default-posts-list-mode', 'list' ) : $_REQUEST['mode'];

Now, go into your theme's functions.php file and add the following code:

add_filter( 'default-posts-list-mode', 'my-default-posts-list-mode' );
function my-default-posts-list-mode( $default ) {
    return 'excerpt';
}

This will hook in to the filter and return excerpt mode by default.

Since my personal rule about hacking Core requires that all hacks be contributed back to the project (this way they can be rolled into Core and no longer count as a hack), I've opened a Trac ticket for this enhancement and submitted the code above as a patch. Please weigh in on the ticket so that it can get into core for 3.5 (we're too late in the cycle for 3.4, but we can try to push this through for the next version).

share|improve this answer
1  
Very cool. Definitely think "this" is a reason to hack the core - so in the future, you don't have to :) –  Zach Mar 30 '12 at 16:02
1  
There's ongoing discussion on this ticket as well - plus a further patch proposing a user option instead of just a filter. Please keep track of that conversation if you decide to actually hack Core ... because if/when things change in a future release, you'll need to change your code as well. –  EAMann Mar 30 '12 at 17:42
    
Why not just hack the $_REQUEST global on add_action( 'edit.php', ... ) and the like, while we wait for core to adopt the patch/proposal? –  soulseekah Mar 30 '12 at 17:44
1  
+1 for getting it on the road to core with some great patches, hopefully we'll see the changesets soon. –  soulseekah Mar 30 '12 at 18:32
1  
+1 from me for getting this on to the core. –  Hosh Sadiq Mar 30 '12 at 21:43
show 1 more comment

Your Answer

 
discard

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.