Argumente an einen Rückruf einer Admin-Menüseite übergeben?

14

Situation: Ich arbeite an einem Plugin und entwickle es als Klasse. Alles hat gut funktioniert, bis ich auf diese Situation gestoßen bin. Ich wollte die Dinge ein bisschen sauberer machen und versuchte dies ..

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

Ich habe verschiedene Optionen ausprobiert, aber es funktioniert nichts. Vielleicht bin ich davor, aber ich kann es nicht sehen.

Natürlich ist dies eine Neuerstellung. Ich habe allen meinen Funktionen ein Präfix vorangestellt und sie sind nicht genau so, wie ich sie hier geschrieben habe, aber ich hoffe, Sie haben die Idee, nach der ich frage.

Danke im Voraus.

PD: Wenn Sie den Original-Quellcode sehen möchten, füge ich ihn gerne ein und gebe Ihnen den Link.

Luis
quelle

Antworten:

8

Sie können der Rückruffunktion kein Argument übergeben. add_menu_page()Fügt es als Aktionshandler hinzu und admin.phplöst die Aktion ohne Argumente aus.

Ich sehe zwei einfache Lösungen für dieses Problem. Eine besteht darin, alle Dateinamen in einem Array in Ihrer Klasse zu speichern, das nach dem Hook-Namen indiziert ist. Dann können Sie hier nachsehen, welche Datei Sie laden müssen (Sie können auch zusätzliche Daten in diesem Array speichern).

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

Das andere ist, das Rückrufargument zu überspringen, damit WordPress die Datei, die durch den Slug-Namen selbst angegeben ist, einschließt, wie Brady in seiner Antwort vorschlägt.

Jan Fabry
quelle
ah-ha, warum habe ich nicht daran gedacht, es so zu machen :(
Brady
JA!! Sie haben heute Dutzende von Kätzchen gerettet. Noch nie von dieser Funktion gehört, obwohl 'current_filter'. Sehr clevere Lösung. Vielen Dank für Ihre Hilfe @ Brady @ Jan Fabry
Luis
4

Sie könnten immer nur eine anonyme Funktion (oder Schließung) verwenden. Etwas zu den Auswirkungen von:

add_menu_page( $page, $menu, $capability, $slug, function() { print_my_admin_page($with_args); }, $icon, $position);
user35752
quelle
1
Das funktioniert bei mir nicht. Ich benutze WordPress 4.1 (und ab heute 4.1.1)
Jeff
Klug! Und es funktioniert. Hier ist ein vollständigeres Beispiel: hastebin.com/segibugice, das eine URL wie example.com/wp-admin/admin.php?page=my-slug
Quinn Comendant
Ich hätte erwähnen sollen, dass Sie bei der Übergabe von Variablen in den Bereich einer anonymen Funktion das Schlüsselwort "use" verwenden müssen. function() use ($my_var) { // now you can use $my_var }
user35752
0

Die Funktion load_view sollte so aussehen:

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

und in Ihrer Include-Datei sollte es jeglichen Inhalt für die angezeigte Seite wiedergeben.

BEARBEITEN:

Folgendes sagt der Kodex dazu:

$menu_slug (string) (required)Der Slug-Name, mit dem auf dieses Menü verwiesen wird (sollte für dieses Menü eindeutig sein). Vor Version 3.0 wurde dies als Datei- (oder Handle-) Parameter bezeichnet. Wenn der Funktionsparameter weggelassen wird, sollte menu_slug die PHP-Datei sein, die die Anzeige des Inhalts der Menüseite übernimmt. Standardeinstellung: Keine

$function Die Funktion, die den Seiteninhalt für die Menüseite anzeigt. Technisch gesehen ist der Funktionsparameter optional, aber wenn er nicht angegeben wird, geht WordPress grundsätzlich davon aus, dass durch das Einbeziehen der PHP-Datei der Verwaltungsbildschirm generiert wird, ohne eine Funktion aufzurufen. Die meisten Plug-in-Autoren fügen den Code zur Seitenerstellung in eine Funktion in ihrer Haupt-Plug-in-Datei ein. Wenn der Funktionsparameter angegeben ist, kann für den Dateiparameter eine beliebige Zeichenfolge verwendet werden. Dies ermöglicht die Verwendung von Seiten wie? Page = my_super_plugin_page anstelle von? Page = my-super-plugin / admin-options.php.

Was ich daraus entnehmen kann ist, dass, wenn Sie die Funktion leer lassen, versucht wird, eine PHP-Datei einzuschließen, die auf dem basiert, was Sie eingestellt haben menu_slug.

BEARBEITEN 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
quelle
@Brady Ich weiß das, und die Funktion "load_view" funktioniert gut und gibt den Inhalt korrekt aus, wenn ein statischer Wert verwendet wird. Zum Beispiel: incl .... / views / my-panel.php ');
Luis
@ Luis - Was ist dann das Problem?
Brady
@Brady-Array (& $ this, 'load_view') // Wo gebe ich den Wert von $ filename an? Ich kann so etwas wie array (& $ this, 'load_view ("my-value")') nicht ausführen. Ich möchte einen Weg finden, um Parameter an die von mir aufgerufene Funktion zu übergeben
Luis
Oh, ich verstehe es jetzt. Sie möchten eine Klassenfunktion aber mit einem Parameter übergeben. Nun, ich habe gesucht und gesucht und kann nicht finden, wie Sie es tun. Aber da Sie die Klasse bestehen, können Sie dann nicht tun, was ich in EDIT 2 eingegeben habe?
Brady
@Brady: Ihre zweite Bearbeitung wird nicht viel helfen, Sie überschreiben einfach die filenameVariable, so wird es immer sein "somethingelse". Ihre erste Änderung könnte hier der Trick sein: Wenn Sie load_viewnichts tun, außer die Datei einzuschließen, sollten Sie in der Tat keine Rückruffunktion übergeben, und WordPress wird versuchen, die Seite, die Sie übergeben haben, als Slug zu laden.
Jan Fabry
0

Ich habe dieses Problem gelöst, indem ich einfach die ID (oder die Daten, die Sie benötigen) an den Menüpunkt angehängt habe.

Beispielsweise:

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

Dies erstellt dann eine URL mit 'my-plugin-settings-filename' (als Beispiel) und ich kann nur diesen Teil der URL analysieren (mit $ _GET oder filter_input).

Jeff
quelle
Sie können auch einen URL-Parameter verwenden, aber Sie müssen ein Menüelement erstellen (und dann können Sie es ausblenden, wenn Sie möchten).
Jeff
Danke, dass du meinen Code toscho in einen Codeblock gesetzt hast. Wenn ich eine Frage stelle, gibt es einen Knopf dafür, aber ich bin nicht mit dem Markup vertraut, um es in einer Antwort zu tun.
Jeff
0

Basierend auf der Antwort von user35752 können Sie sogar eine Objektmethode mit params als Rückruf verwenden.

$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)
Lordgretix
quelle