¿Cómo manejo mejor las acciones de la página de complementos personalizados?

21

Constantemente me encuentro con la misma molestia, así que pensé en ver si hay alguna idea o experiencia por ahí ...

He creado un complemento que usa su propia página de administración. Tiene que. Ahora que resolví las cosas WP_List_Table (), debo decir que es genial ... pero ...

Las páginas de complementos personalizados siempre se cargan como a admin.php?page=...menos que quiera cargarlas directamente desde el directorio de complementos, lo cual no hago. Ahora, si hago una 'acción' desde esa página, necesito procesarla de alguna manera y luego redirigirla nuevamente a la página sin el parámetro de acción. No importa si hago GET o POST, de verdad.

En todas sus páginas internas, WP hace esto en la misma página, comprueba si hay una acción, si es así, la procesa y luego la redirige a sí misma sin la acción. Esto es posible porque admin-headertodavía no se ha cargado en estas páginas .

Sin embargo, si intenta hacerlo en su propia página, la mitad de la interfaz de administración ya se ha enviado al navegador, por lo que ya no es posible una redirección. Claramente, la solución es POST / GET directamente a otra página, cargar el marco WP en eso, hacer el procesamiento y luego redirigir de nuevo a la página original ... pero ... eso es un poco molesto, porque ... mi original La página se carga a través de una devolución de llamada, por lo que se ejecuta dentro de un método de mi clase. Eso es hermoso.

Si cargo una página separada, tengo que incluir manualmente wp-load.phpy estoy fuera de mi clase, lo cual es molesto, y en mi caso particular me molesta especialmente, porque solo estoy instanciando mi clase de complemento de forma anónima para que nadie pueda acceder a ella. desde fuera.

Entonces, después de esta larga historia ... ¿alguien encontró una buena solución para cargar otra página a través de una devolución de llamada sin tener toda la interfaz de administración configurada a su alrededor?

(Conozco una solución alternativa ... puedo conectar una función load-....que verifica el parámetro de acción y procesa y redirige. Pero me pregunto si hay una mejor manera).

Gracias.

wyrfel
fuente
¿Por qué se etiqueta esto [plugin-wp-pagenavi]?[plugin-development]es ciertamente bienvenido aquí.
Jan Fabry
@ Jan Fabry: No estoy seguro de qué plugin-wp-pagenavi sirve ... estaba asumiendo que era por cosas relacionadas con la correlación entre los complementos y el menú de administración. Como mi pregunta está relacionada con eso, seleccioné esa etiqueta.
wyrfel
WP-PageNavi es un complemento con una navegación de paginación más avanzada para el front-end. Podrías usar[admin-menu] aquí, pero no creo que esté realmente relacionado con eso. Cambié las etiquetas a lo que creo que le queda, por supuesto, puede editarlo nuevamente.
Jan Fabry
@ Jan Fabry: Gracias por volver a etiquetar ... todavía no estoy familiarizado con todo el conjunto de etiquetas (obviamente).
wyrfel

Respuestas:

28

Como regla general, debe utilizar una solicitud POST para la mayoría de las acciones, para asegurarse de que no se ejecuten por accidente . Pero también es una buena práctica redirigir a una página normal después de una solicitud POST, para evitar la ejecución duplicada cuando el usuario actualiza la página.

Entonces el flujo es así:

  1. Su página de complementos con un formulario POST, que se envía a
  2. Una página que maneja la solicitud, que redirige a
  3. Su página de complementos, que muestra el resultado de la acción

La página central no tiene que ser su página de complemento. Esto significa que puede usar el "controlador POST genérico" que se incluyó hace tres años, el 'admin_action_' . $_REQUEST['action']enlaceadmin.php .

Un usuario de ejemplo es el complemento Akismet . Si desea utilizarlo de manera confiable, debe enviarlo admin.phpdirectamente , no a otra página que incluya admin.php.

Aquí hay un ejemplo muy básico de cómo usarlo:

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
}
Jan Fabry
fuente
Hei, volveré a mirar el código, obviamente no lo vi, pero solo para confirmar ... así que lo que estás diciendo es que si llamo a admin.php directamente sin un parámetro de página, se salta toda la página cargando y solo hace un poco de inicialización y ejecuta el gancho? Eso sería increíble ... ish (todavía no entiendo por qué no pusieron el gancho antes de cargar la página).
wyrfel
@wyrfel: Sí, llamar admin.phpdirectamente es el "truco" que me enseñó la fuente de Akismet. Tiene razón cuando está mostrando un formulario y desea volver a mostrarlo en caso de errores: entonces sería fácil si el destino es su página de complementos pero se engancha en algún lugar al inicio (para que pueda redirigir si tiene éxito o mostrar el formulario de nuevo con mensajes de error si no). ¿Quizás lo sugiera en un boleto de Trac?
Jan Fabry
Presentaré un boleto. Como solución alternativa, encontré que el 'load-<pagehook>'gancho funcionaba ... se llama antes de que se cargue la página ... pero el admin_action_...concepto parece mucho más agradable y más específico. Además, en una nota, los mensajes de error siguen siendo problemáticos si realiza POST y no desea volver a publicar en la recarga, pero ese es un tema diferente.
wyrfel
@wyrfel: ¿Por qué los mensajes de error seguirían siendo problemáticos? Si hay un mensaje de error, quédese en la página y vuelva a mostrar el formulario con los mensajes (por supuesto, una actualización no tendría mucho sentido aquí, pero tampoco sería perjudicial, porque los errores seguirían allí y no se realizarán acciones) ser ejecutado). Si no hay errores, ejecute la acción y redirija a una página de resumen "segura". Esto funcionaría si el admin_action_gancho se moviera antes que el cargador de páginas del complemento.
Jan Fabry
Ok ... estaba pensando demasiado complicado.
wyrfel
3

Abordé esto de manera ligeramente diferente simplemente agregando noheader = true a la url de acción en la página donde el usuario envía la acción

Luego, mi controlador realiza la acción (es decir, normalmente, agregar, actualizar o eliminar) y luego termina con un wp_redirect () a la siguiente acción de página (por ejemplo, agregar página -> editar página, eliminar página -> lista de páginas, editar página -> editar página ) También paso un mensaje en la URL para que pueda mostrar un estado como actualización exitosa o fallida.

Este enfoque mantiene todas las acciones: enumerar, agregar, editar, eliminar, eliminar en masa, etc. en la misma clase y con la misma babosa de administración, por lo que es bastante fácil de mantener y comprender.

Russell Jamieson
fuente
Hombre, eres un genio! He estado luchando durante dos días seguidos y parece que todo lo que necesitaba era la parte "noheader = true". ¡Gracias!
r00m
0

Otro enfoque diferente es simplemente agregar un campo de entrada oculto al formulario:

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

De esta manera, WordPress parece manejar la redirección automáticamente.

simonthesorcerer
fuente