将参数传递给管理菜单页面回调?


14

情况:我正在开发一个插件,并且正在将其作为一个类进行开发,一切正常,直到遇到这种情况。我想把事情弄干净一点,然后尝试一下。

class MyPlugin {
    function __construct() {
        add_action('admin_menu', array(&$this, 'myplugin_create_menus');
    }        

    //I don't want to write a function for every options page I create
    //so I prefer to just load the content from an external file.        
    function load_view($filename) {
        $view = require(dirname(__FILE__).'/views/'.$filename.'.php');
        return $view;
    }

    //Here is where the problem comes
    function myplugin_create_menus() {
        add_menu_page( 'Plugin name',
                       'Plugin name',
                       'manage_options',
                       'my-plugin-settings',
                       array(&$this, 'load_view') // Where do I specify the value of $filename??
                     );
    }

}#end of class

我尝试了很多不同的选项,但没有任何效果,也许我在它前面,但我看不到它。

当然,这是一个重新创建,我为所有函数添加了前缀,它们与我在此处编写的功能不完全相同,但我希望您能理解我的要求。

提前致谢。

PD:如果您想查看原始源代码,我将很高兴将其粘贴并提供链接。

Answers:


8

您不能将参数传递给回调函数。add_menu_page()将其添加为动作处理程序,并admin.php触发动作,不带任何参数。

我看到了两个简单的解决方案。一种方法是将所有文件名存储在类中的数组中,并按挂钩名称索引。然后,您可以使用它来查找需要加载的文件(也可以在此阵列中存储其他数据)。

class WPSE16415_Plugin
{
    protected $views = array();

    function load_view() {
        // current_filter() also returns the current action
        $current_views = $this->views[current_filter()];
        include(dirname(__FILE__).'/views/'.$current_views.'.php');
    }

    function myplugin_create_menus() {
        $view_hook_name = add_menu_page( 'Plugin name',
            'Plugin name',
            'manage_options',
            'my-plugin-settings',
            array(&$this, 'load_view'),
        );
        $this->views[$view_hook_name] = 'options';
    }
}

另一个是跳过回调参数,因此WordPress将包括由子弹名称本身指示的文件,正如布雷迪在回答中所建议的那样。


啊哈,我为什么不这么想呢:(
布雷迪

是的!您今天拯救了数十只小猫。.虽然“ current_filter”从未听说过该功能。非常聪明的解决方案。非常感谢您的帮助@Brady @Jan Fabry
路易斯

4

您总是可以只使用匿名函数(或闭包)。影响:

add_menu_page( $page, $menu, $capability, $slug, function() { print_my_admin_page($with_args); }, $icon, $position);

1
这对我不起作用。我正在使用WordPress 4.1(今天是4.1.1)
Jeff Vdovjak 2015年

聪明!它确实有效。这是一个更完整的示例:hastebin.com/segibugice,它会生成类似example.com/wp-admin/admin.php?page=my-slug
Quinn Comendant

在将变量传递到匿名函数的范围时,我应该提到过,您必须使用“ use”关键字。function() use ($my_var) { // now you can use $my_var }
user35752

0

函数load_view应该是这样的:

function load_view($filename) {
    include(dirname(__FILE__).'/views/'.$filename.'.php');
}

并且在您的包含文件中,它应回显正在显示的页面的任何内容。

编辑:

这是法典对此事的说明:

$menu_slug (string) (required)引用此菜单所用的子文件名(此菜单应唯一)。在3.0版之前,这称为文件(或句柄)参数。如果省略function参数,则menu_slug应该是处理菜单页面内容显示的PHP文件。默认值:无

$function 显示菜单页面的页面内容的功能。从技术上讲,function参数是可选的,但如果未提供,则WordPress将基本上假定包括PHP文件在内的将生成管理屏幕,而无需调用函数。大多数插件作者选择将页面生成代码放入其主插件文件中的函数中。:如果指定了function参数,则可以使用任何字符串作为file参数。这允许使用诸如?page = my_super_plugin_page之类的页面,而不是?page = my-super-plugin / admin-options.php。

因此,我可以从中收集的信息是,如果您将函数留空,它会根据您设置的内容尝试包含一个php文件menu_slug

编辑2

function load_view() {
    include(dirname(__FILE__).'/views/'.$this->filename.'.php');
}

function myplugin_create_menus() {
    $this->filename = "something";
    add_menu_page( 'Plugin name',
                   'Plugin name',
                   'manage_options',
                   'my-plugin-settings',
                   array(&$this, 'load_view')
                 );
    $this->filename = "somethingelse";
    add_menu_page( 'Plugin name',
                   'Plugin name',
                   'manage_options',
                   'my-plugin-settings',
                   array(&$this, 'load_view')
                 );
}

@Brady我知道,函数“ load_view”运行良好,并且在使用静态值时可以正确输出内容。例如:incl .... / views / my-panel.php');
路易斯

@Luis-那么问题是什么?
布雷迪

@Brady array(&$ this,'load_view')//我在哪里指定$ filename的值?我无法做类似array(&$ this,'load_view(“ my-value”)')之类的事情,我想找到一种将参数传递给我要调用的函数的方法
路易斯

哦,我明白了。您想传递一个带有参数的类函数。我已经看了又看,却找不到你怎么做。但是,由于您正在通过课程,所以您不能做我在编辑2中所做的事情吗?
布雷迪

@Brady:您的第二次编辑无济于事,您只需要覆盖filename变量即可,它将始终为"somethingelse"。您的第一个编辑可能是这里的窍门:如果load_view除了包含文件之外什么也不做,您实际上不应该传递回调函数,并且WordPress将尝试加载您以slug形式传递的页面。
1

0

我通过将ID(或所需的任何数据)附加到菜单项来解决了这个问题。

例如:

 add_menu_page( 'Plugin name',
                       'Plugin name',
                       'manage_options',
                       'my-plugin-settings-' . $identifier,
                       'setting-function-callback'
                     );

然后,这将创建一个带有“ my-plugin-settings-filename”的URL(例如),我可以解析URL的那一部分(使用$ _GET或filter_input)。


您也可以使用URL参数,但是必须创建一个菜单项(然后可以根据需要将其隐藏)。
Jeff Vdovjak

感谢您将我的代码放入toscho代码块中。当我问一个问题时,有一个按钮,但是我对答案中的标记并不熟悉。
Jeff Vdovjak,2015年

0

根据user35752的答案,您甚至可以使用带params作为回调的对象方法。

$args = [ [new Foo(), 'bar'], [$param1, $param2, ...] ];

$callback = function () use ($args){
                call_user_func_array($args[0], $args[1]);
            };
add_menu_page( $page, $menu, $capability, $slug, $callback , $icon, $position)
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.