我如何最好地处理自定义插件页面操作?


21

我经常遇到同样的烦恼,所以我想看看是否有任何想法或经验。

我创建了一个使用其自己的管理页面的插件。它必须。现在,我整理出了WP_List_Table()的内容,我必须说这很棒...但是...

自定义插件页面始终加载,admin.php?page=...除非我不希望直接从插件目录加载它们。现在,如果我从该页面执行“操作”,则需要以某种方式进行处理,然后将其重定向回该页面而不使用action参数。真的,不管我执行GET还是POST。

WP在所有内部页面上都在同一页面上执行此操作,它检查是否有动作,如果有,则对其进行处理,然后在没有动作的情况下重定向到自身。这是可能的,因为admin-header尚未在这些页面上加载。

但是,如果您尝试在自己的页面上执行此操作,则一半的管理界面已发送到浏览器,因此无法再进行重定向。显然,解决方案是直接POST / GET到另一个页面,在该页面上加载WP框架,进行处理,然后重定向回原始页面...但是...有点烦人,因为...我的原始页面是通过回调加载的,因此它在我的类的方法中运行。那好美丽。

如果我加载一个单独的页面,则必须手动添加wp-load.php并且不在类的范围内,这很烦人,在我的情况下,这尤其会困扰我,因为我只是匿名实例化了我的插件类,因此没有人可以访问它从外部。

因此,经过漫长的故事之后...有人提出了一个很好的解决方案来通过回调加载另一个页面而又没有设置整个管理界面吗?

(我知道一种解决方法...我可以将一个函数挂接到其中load-....,以检查action参数,然后进行处理和重定向。但是我想知道是否有更好的方法。)

谢谢。


为什么用标记[plugin-wp-pagenavi][plugin-development]这里肯定是受欢迎的。
1月Fabry

@Jan Fabry:不确定plugin-wp-pagenavi是为了什么……我以为这是关于插件和管理菜单之间的相关性的事情。由于我的问题与此有关,因此我选择了该标签。
wyrfel 2011年

WP-PageNavi是一个具有前端更高级分页导航功能的插件。您可以[admin-menu]在这里使用,但我认为这与之无关。我将标签更改为我认为合适的标签,您当然可以再次对其进行编辑。
日,扬·法布里

@Jan Fabry:感谢您进行重新标记...对整个标记池还不是很熟悉,(显然)。
wyrfel 2011年

Answers:


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票中建议呢?
1

我要出票。作为一种解决方法,我发现该'load-<pagehook>'钩子可以正常工作了……在页面加载之前被调用了……但是这个admin_action_...概念似乎更好很多,也更具体了。另外,请注意,如果您执行POST并不想在重新加载时重新发布,则错误消息仍然存在问题,但这是一个不同的主题。
wyrfel 2011年

@wyrfel:为什么错误消息仍然有问题?如果出现错误消息,请停留在页面上并再次显示带有消息的表单(当然,刷新在这里没有多大意义-但这也不会造成任何危害,因为错误仍然存​​在,并且不会采取任何措施。被执行)。如果没有错误,请执行操作并重定向到“安全”概述页面。如果admin_action_钩子在插件页面加载器之前被移动,这将起作用。
1

好的...我当时想的太复杂了。
wyrfel 2011年

3

我通过在用户提交执行该操作的页面上的操作URL上简单添加noheader = true来实现这一点

然后,我的处理程序执行操作(即通常是添加,更新或删除),然后以wp_redirect()结束下一页操作(例如,添加页面->编辑页面,删除页面->列表页面,编辑页面->编辑页面) )。我还在URL上传递了一条消息,因此可以显示诸如更新成功或失败之类的状态。

这种方法将所有操作保持在同一类中,并且使用相同的管理子项列出,添加,编辑,删除,批量删除等,因此非常易于维护和理解。


天哪,你真是天才!我已经连续挣扎了两天,看来我所需要的只是“ noheader = true”部分。谢谢!
r00m 2014年

0

另一种不同的方法是在表单中添加一个隐藏的输入字段:

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

这样,WordPress似乎可以自动处理重定向。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.