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!
3 Answers
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.
-
1Good 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! Mar 30, 2012 at 21:39
-
Thank you, glad to have been of help. A very interesting question. Mar 30, 2012 at 21:58
-
Thanks for this @soulseekah, I used this too and works great. As you mentioned at the time "WordPress 3.5 is still quite far away" - is this code still good to use with latest WordPress version? Jul 3, 2015 at 10:22
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).
-
1Very cool. Definitely think "this" is a reason to hack the core - so in the future, you don't have to :)– ZachMar 30, 2012 at 16:02
-
1There'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.– EAMannMar 30, 2012 at 17:42
-
Why not just hack the
$_REQUEST
global onadd_action( 'edit.php', ... )
and the like, while we wait for core to adopt the patch/proposal? Mar 30, 2012 at 17:44 -
@Soulseekah Good alternative ... just not a fan of hacking the
$_REQUEST
object myself. Feel free to post another answer outlining how it could be done.– EAMannMar 30, 2012 at 17:56 -
1+1 for getting it on the road to core with some great patches, hopefully we'll see the changesets soon. Mar 30, 2012 at 18:32
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.
-
1This makes sense. However,
paged
is not taken into account (pagination) + usingwp_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. Mar 30, 2012 at 22:03 -
2My 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.– EAMannMar 30, 2012 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. Mar 30, 2012 at 23:27