Как мне лучше всего обрабатывать пользовательские действия на странице плагина?

21

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

Я создал плагин, который использует свою собственную страницу администратора. Он должен. Теперь, когда я разобрался с WP_List_Table (), я должен сказать, что это здорово ... но ....

Пользовательские страницы плагинов всегда загружаются, admin.php?page=...если только я не хочу загружать их непосредственно из каталога плагинов, чего я не делаю. Теперь, если я выполняю «действие» на этой странице, мне нужно как-то обработать его, а затем перенаправить обратно на страницу без параметра действия. Неважно, если я делаю GET или POST, на самом деле.

На всех своих внутренних страницах WP делает это на одной и той же странице, проверяет, есть ли какое-либо действие, обрабатывает ли его и затем перенаправляет на себя без действия. Это возможно, потому что на этих страницах admin-headerеще не было загружено.

Однако если вы попытаетесь сделать это на своей странице, половина интерфейса администратора уже отправлена ​​в браузер, поэтому перенаправление больше невозможно. Понятно, что решение состоит в том, чтобы POST / GET напрямую перейти на другую страницу, загрузить на нем платформу WP, выполнить обработку и затем перенаправить обратно на исходную страницу ... но ... это немного раздражает, потому что ... мой оригинал страница загружается с помощью обратного вызова, поэтому она запускается в методе моего класса. Это красиво.

Если я загружаю отдельную страницу, мне нужно вручную включить ее, wp-load.phpи я нахожусь за пределами моего класса, что раздражает, и в моем конкретном случае это меня особенно беспокоит, потому что я только создаю экземпляр своего класса плагина анонимно, чтобы никто не мог получить к нему доступ. снаружи.

Итак, после этой длинной истории ... кто-нибудь придумал хорошее решение для загрузки другой страницы с помощью обратного вызова, не настроив весь интерфейс администратора?

(Я знаю обходной путь ... я могу подключить функцию, load-....которая проверяет параметр action, выполняет обработку и перенаправление. Но мне интересно, есть ли лучший способ.)

Спасибо.

wyrfel
источник
Почему это помечено [plugin-wp-pagenavi]? [plugin-development]безусловно, приветствуется здесь.
Ян Фабри
@Jan Fabry: Не уверен, что plugin-wp-pagenaviдля ... я предполагал, что это было для вещей, касающихся корреляции между плагинами и меню администратора. Так как мой вопрос связан с этим, я выбрал этот тег.
wyrfel
WP-PageNavi - это плагин с расширенной навигацией для внешнего интерфейса. Вы можете использовать [admin-menu]здесь, но я не думаю, что это действительно связано с этим. Я изменил теги так, как мне кажется, он подходит, вы, конечно, можете снова его редактировать.
Ян Фабри
@Jan Fabry: Спасибо за повторную пометку ... пока не знаком со всем пулом тегов (вполне очевидно).
wyrfel

Ответы:

28

Как правило, для большинства действий следует использовать запрос POST, чтобы убедиться, что они не выполнены случайно . Но также рекомендуется перенаправлять на обычную страницу после запроса POST, чтобы предотвратить дублирование при обновлении страницы пользователем.

Итак, поток такой:

  1. Ваша страница плагина с формой POST, которая отправляет
  2. Страница, которая обрабатывает запрос, который перенаправляет на
  3. Ваша страница плагина, которая показывает результат действия

Средняя страница не должна быть вашей страницей плагина. Это означает , что вы можете использовать «общий обработчик POST» , который включал в себя три года назад, на 'admin_action_' . $_REQUEST['action']крючокadmin.php .

Примером пользователя является плагин Akismet . Если вы хотите использовать его надежно, вы должны подчиниться admin.phpнепосредственно , а не другой странице, которая включает в себя admin.php.

Вот очень простой пример того, как его использовать:

add_action( 'admin_action_wpse10500', 'wpse10500_admin_action' );
function wpse10500_admin_action()
{
    // Do your stuff here

    wp_redirect( $_SERVER['HTTP_REFERER'] );
    exit();
}

add_action( 'admin_menu', 'wpse10500_admin_menu' );
function wpse10500_admin_menu()
{
    add_management_page( 'WPSE 10500 Test page', 'WPSE 10500 Test page', 'administrator', 'wpse10500', 'wpse10500_do_page' );
}

function wpse10500_do_page()
{
?>
<form method="POST" action="<?php echo admin_url( 'admin.php' ); ?>">
    <input type="hidden" name="action" value="wpse10500" />
    <input type="submit" value="Do it!" />
</form>
<?php
}
Ян Фабри
источник
Привет, я еще раз посмотрю на код, я, очевидно, не видел этого, но просто для подтверждения ... так что вы говорите, что если я вызываю admin.php напрямую без параметра страницы, он пропускает всю страницу загрузка и просто делает некоторую инициализацию и запускает ловушку? Это было бы здорово ... иш (я до сих пор не понимаю, почему они не установили хук перед загрузкой страницы).
wyrfel
@wyrfel: Да, звонки admin.phpнапрямую - это «трюк», которому научил меня источник в Akismet. Вы правы, когда отображаете форму и хотите снова отобразить ее в случае ошибок: тогда было бы легко, если бы местом назначения была ваша страница плагина, но где-то хук где-то в начале (чтобы вы могли перенаправить в случае успеха или отобразить Форма снова с сообщениями об ошибках, если нет). Может быть, предложить это в билете Trac?
Ян Фабри
Я запишу билет. В качестве обходного пути я обнаружил, что 'load-<pagehook>'зацепка работает ... она вызывается перед загрузкой страницы ... но admin_action_...концепция кажется намного приятнее и конкретнее. Кроме того, на заметку, сообщения об ошибках все еще проблематичны, если вы делаете POST и не хотите перепечатывать при перезагрузке, но это другая тема.
wyrfel
@wyrfel: Почему сообщения об ошибках все еще могут быть проблематичными? Если есть сообщение об ошибке, оставайтесь на странице и снова отображайте форму с сообщениями (конечно, обновление не имело бы особого смысла - но это также не принесло бы вреда, потому что ошибки все еще были бы там, и никакие действия не будут быть казненным). Если ошибок нет, выполните действие и перенаправьте на «безопасную» страницу обзора. Это будет работать - если admin_action_хук будет перемещен перед загрузчиком страниц плагина.
Ян Фабри
Хорошо ... я думал слишком сложно.
wyrfel
3

Я подошел к этому немного по-другому, просто добавив noheader = true к URL-адресу действия на странице, где пользователь отправляет действие.

Мой обработчик затем выполняет действие (т.е. обычно добавляет, обновляет или удаляет), затем завершает с помощью wp_redirect () до следующего действия страницы (например, добавить страницу -> изменить страницу, удалить страницу -> список страниц, изменить страницу -> изменить страницу ). Я также передаю сообщение по URL-адресу, чтобы отображать состояние, такое как обновление прошло успешно или не удалось.

Этот подход сохраняет все действия: список, добавление, редактирование, удаление, массовое удаление и т. Д. В одном и том же классе и с одним и тем же административным портом, поэтому его довольно легко поддерживать и понимать.

Рассел Джеймисон
источник
Человек, ты гений! Я боролся два дня подряд, и, похоже, все, что мне было нужно, это часть «noheader = true». Благодарность!
rmm
0

Другой другой подход - просто добавить скрытое поле ввода в форму:

<input type="hidden" name="page" value="your-page-slug" />

Таким образом, WordPress, кажется, обрабатывает перенаправление автоматически.

simonthesorcerer
источник