Установить список по умолчанию «Просмотр» в Admin

8

Я ищу способ установить параметры «Просмотр» по умолчанию для типов сообщений в области администратора. Например, по умолчанию сообщения будут по умолчанию отображать «список» вместо «отрывок» - я хотел бы изменить это на отрывок по умолчанию - что будет лучшим способом для достижения этого? Я немного искал по этому вопросу, но пока застрял в грязи. Любая помощь будет принята с благодарностью. Спасибо!

Zach
источник

Ответы:

9

Хотя наличие постоянных настроек в ядре - это хорошо, может пройти довольно много времени, прежде чем оно действительно будет принято. WordPress 3.5 все еще довольно далеко.

Так что давайте добавим глобальный $_REQUESTмассив вместо этого.

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

Это заблокирует режимы, заставляя excerptрежим все время, поэтому давайте по очереди позволим пользователю решать, но сохраняем его постоянным, используя метаданные пользователя:

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;
}

Вы можете дополнительно интерполировать post_typeвсе, принимая во внимание $_GET['post_type']переменную, когда она доступна.

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;
}

Виола! Режим постоянного списка для каждого типа поста на пользователя, без хаков.

soulseekah
источник
1
Хорошее решение Вскоре после того, как я положил награду за это, мне стало намного легче! Но, поскольку у вас есть решение, я дам вам награду, хотя я думаю, что вместо этого я включу ваш способ, поскольку он на самом деле является постоянным, а не похожим на поведение по умолчанию, за исключением отрывка вместо списка. Отредактируйте, можете наградить его за 17 часов, так что терпите меня!
Хош Садик
Спасибо, рад помочь. Очень интересный вопрос
soulseekah
Спасибо за это @soulseekah, я тоже этим пользовался и прекрасно работает. Как вы упомянули в то время, «WordPress 3.5 все еще довольно далеко» - хорошо ли использовать этот код с последней версией WordPress?
user3438958
5

Экран просмотра постов переключается с просмотра списка на просмотр фрагментов в зависимости от значения параметра mode в строке запроса. Если параметр «mode» не задан, WordPress по умолчанию принимает вид списка.

К сожалению, этот параметр не фильтруется, поэтому нет простого способа контролировать его программно.

Поэтому я собираюсь сделать то, чего никогда не делаю ... Я расскажу вам, как взломать Core, чтобы сделать эту работу ...

Добавление фильтра

Откройте /wp-admin/includes/class-wp-posts-list-table.phpи найдите prepare_items()метод (около строки 81).

В строке 99 WordPress проверяет, был ли параметр «режим» установлен в запросе, и использует его для установки глобальной $modeпеременной:

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

Мы собираемся изменить эту строку, чтобы отфильтровать настройки по умолчанию. Измените эту строку на:

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

Теперь перейдите в functions.phpфайл вашей темы и добавьте следующий код:

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

Это подключится к фильтру и вернет режим выписки по умолчанию.

Так как мое личное правило о взломе Core требует, чтобы все хаки были внесены обратно в проект (таким образом они могут быть перенесены в Core и больше не считаться хаком), я открыл Trac-тикет для этого улучшения и отправил код выше как патч. Пожалуйста, взвесьте тикет, чтобы он мог войти в ядро ​​для 3.5 (мы опоздали в цикле для 3.4, но мы можем попытаться протолкнуть это для следующей версии).

EAMann
источник
1
Очень круто. Определенно думаю, что «это» является причиной взломать ядро ​​- так что в будущем вам не придется :)
Зак
1
Также продолжается обсуждение этого тикета - плюс еще один патч, предлагающий пользовательскую опцию вместо простого фильтра. Пожалуйста, следите за этим разговором, если вы решите взломать Core ... потому что, если / когда что-то изменится в будущем выпуске, вам также придется изменить свой код.
EAMann
Почему бы просто не взломать $_REQUESTглобальный add_action( 'edit.php', ... )и тому подобное, пока мы ждем, когда ядро ​​примет исправление / предложение?
soulseekah
@Soulseekah Хорошая альтернатива ... просто не фанат взлома $_REQUESTобъекта сам. Не стесняйтесь опубликовать еще один ответ с изложением того, как это можно сделать.
EAMann
1
+1 за продвижение к ядру с отличными патчами, надеюсь, скоро мы увидим изменения.
soulseekah
2

Итак, вскоре после того, как я назначил награду, я нашел следующее решение. Это поведение по умолчанию во всех отношениях, за исключением того, что оно выбирает представление выдержки для любого типа сообщения (вместо представления по умолчанию).

<?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;
        }
    }
}

?>

ПРИМЕЧАНИЕ: я рекомендую подход Soulseekah, если вы не хотите, чтобы он запомнил выбор пользователя, вы можете немного включить мой код в его код. ПРИМЕЧАНИЕ 2: Если / когда патч EAMann является частью ядра, очевидно, что его метод будет лучшим, поскольку он не потребует от вас проделать длинный путь. Мне просто не нравится в данный момент, так как вы должны редактировать файлы ядра.

Хош Садик
источник
1
Это имеет смысл. Тем pagedне менее, не принимается во внимание (разбиение на страницы) + использование wp_redirectвместо необработанных заголовков может быть немного "чище", и я не уверен, насколько эффективно перенаправление. Помимо этого выглядит интересно. Кроме того, $_GET['post_type']может не быть установлен, что приводит к предупреждению, если ошибки включены. +1 за усилие и терпение. Не понимал, что вопрос был таким старым.
soulseekah
2
Моя проблема с этим подходом состоит в том, что он включает перенаправление. Таким образом, вы загружаете WP не один раз, а дважды, просто чтобы попасть на страницу публикации сообщений.
EAMann
@Soulseekah, ты прав, не подумал, что я обновил код, чтобы учесть все $_GETпеременные. Что касается $_GET['post_type'], честно говоря, меня это не слишком беспокоило, поскольку я требовал, чтобы это было только для нестандартного типа сообщений, который всегда будет там. Очевидно, это можно опустить. @ EAMann, Вы правы, однако, это было лучшее решение, которое я мог придумать. Я попытался установить $_GETпараметры вручную , надеясь, что они будут установлены ДО того, как они будут прочитаны, но, похоже, это не так.
Хош Садик