Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Situation: I'm working on a plugin and I'm developing it as a class, everything worked fine until I run into this situation. I wanted to make things a bit cleaner and tried this..

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

I've tried a bunch of different options but nothing works, maybe I'm in front of it but I can't see it.

Of course this is a re-creation, I've prefixed all my functions and they are not exactly as I wrote here but I hope you got the idea of I'm asking for.

Thanks in advance.

P.D.: If you want to see the original source code I'll be glad to paste it and give you the link.

share|improve this question

3 Answers 3

up vote 3 down vote accepted

You can't pass an argument to the callback function. add_menu_page() adds it as an action handler, and admin.php fires the action, without any arguments.

I see two simple solutions to this problem. One is to store all filename in an array in your class, indexed by hook name. Then you can use this to look up what file you need to load (you can also store additional data in this array).

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

The other is to skip the callback argument, so WordPress will include the file indicated by the slug name itself, as Brady suggests in his answer.

share|improve this answer
    
ah-ha why didn't I think of doing it that way :( –  Brady May 5 '11 at 16:00
    
YEAH!! you saved dozens of kittens today.. never heard of that function though 'current_filter'. Very clever solution. Thanks a lot for your help @Brady @Jan Fabry –  Luis May 5 '11 at 16:39

the function load_view should be like this?:

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

and in your include file it should echo any content for the page being displayed.

EDIT:

Here is what the codex says on the matter:

$menu_slug (string) (required) The slug name to refer to this menu by (should be unique for this menu). Prior to Version 3.0 this was called the file (or handle) parameter. If the function parameter is omitted, the menu_slug should be the PHP file that handles the display of the menu page content. Default: None

$function The function that displays the page content for the menu page. Technically, the function parameter is optional, but if it is not supplied, then WordPress will basically assume that including the PHP file will generate the administration screen, without calling a function. Most plugin authors choose to put the page-generating code in a function within their main plugin file.:In the event that the function parameter is specified, it is possible to use any string for the file parameter. This allows usage of pages such as ?page=my_super_plugin_page instead of ?page=my-super-plugin/admin-options.php.

So what I can gather from this is that if you leave function empty it tries to include a php file based on what you have set the menu_slug to.

EDIT 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')
                 );
}
share|improve this answer
    
@Brady I know that, and the function "load_view" is working well and outputting the content correctly when using a static value. For example: incl..../views/my-panel.php'); –  Luis May 5 '11 at 10:57
    
@Luis - Then whats the issue? –  Brady May 5 '11 at 10:59
    
@Brady array(&$this, 'load_view') // Where do I specify the value of $filename??. I can't do something like array(&$this, 'load_view("my-value")') I want to find a way to pass parameters to the function I'm calling –  Luis May 5 '11 at 11:31
    
Oh i get it now. You want to pass a class function but with a parameter. Well Ive looked and looked and cannot find how you do it. But since you are passing the class then cannot you do what I have put in EDIT 2? –  Brady May 5 '11 at 12:06
    
@Brady: Your second edit will not help much, you just override the filename variable so it will always be "somethingelse". Your first edit could be the trick here: if load_view does nothing except for including the file, you should indeed not pass a callback function and WordPress will try to load the page you passed as the slug. –  Jan Fabry May 5 '11 at 12:48

You could always just use an anonymous function (or closure). Something to the affect of:

add_menu_page( $page, $menu, $capability, $slug, function() { print_my_admin_page($with_args); }, $icon, $position);
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.