Passare argomenti a una richiamata della pagina del menu di amministrazione?


14

Situazione: sto lavorando su un plugin e lo sto sviluppando come classe, tutto ha funzionato bene fino a quando non mi sono imbattuto in questa situazione. Volevo rendere le cose un po 'più pulite e ho provato questo ...

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

Ho provato un sacco di opzioni diverse ma non funziona nulla, forse ci sono davanti ma non riesco a vederlo.

Naturalmente questa è una ricostruzione, ho anteposto tutte le mie funzioni e non sono esattamente come ho scritto qui, ma spero che tu abbia avuto l'idea di chiedere.

Grazie in anticipo.

PD: Se vuoi vedere il codice sorgente originale, sarò felice di incollarlo e darti il ​​link.

Risposte:


8

Non è possibile passare un argomento alla funzione di callback. add_menu_page()lo aggiunge come un gestore di azioni e admin.phpattiva l'azione , senza alcun argomento.

Vedo due semplici soluzioni a questo problema. Uno è quello di memorizzare tutti i nomi di file in un array nella tua classe, indicizzati dal nome hook. Quindi puoi usarlo per cercare quale file devi caricare (puoi anche memorizzare ulteriori dati in questo 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';
    }
}

L'altro è saltare l'argomento callback, quindi WordPress includerà il file indicato dal nome della lumaca stessa, come suggerisce Brady nella sua risposta.


ah ah ah perché non ho pensato di farlo in questo modo :(
Brady,

SI!! oggi hai salvato dozzine di gattini .. mai sentito parlare di quella funzione tramite 'current_filter'. Soluzione molto intelligente. Grazie mille per il tuo aiuto @ Brad @ Jan Fabry
Luis

4

Puoi sempre semplicemente utilizzare una funzione (o chiusura) anonima. Qualcosa che influisce su:

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

1
Questo non funziona per me. Sto usando WordPress 4.1 (e oggi 4.1.1)
Jeff Vdovjak,

Intelligente! E funziona. Ecco un esempio più completo: hastebin.com/segibugice che genererebbe un URL come example.com/wp-admin/admin.php?page=my-slug
Quinn Comendant

Avrei dovuto menzionare quando si passano le variabili nell'ambito di una funzione anonima, è necessario utilizzare la parola chiave "usa". function() use ($my_var) { // now you can use $my_var }
user35752,

0

la funzione load_view dovrebbe essere così ?:

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

e nel tuo file include dovrebbe fare eco a qualsiasi contenuto per la pagina visualizzata.

MODIFICARE:

Ecco cosa dice il codice in materia:

$menu_slug (string) (required)Il nome della lumaca con cui fare riferimento a questo menu (dovrebbe essere univoco per questo menu). Prima della versione 3.0 questo era chiamato il parametro file (o handle). Se il parametro della funzione viene omesso, menu_slug dovrebbe essere il file PHP che gestisce la visualizzazione del contenuto della pagina del menu. Predefinito: Nessuno

$function La funzione che visualizza il contenuto della pagina per la pagina del menu. Tecnicamente, il parametro della funzione è facoltativo, ma se non viene fornito, WordPress supporrà sostanzialmente che l'inclusione del file PHP genererà la schermata di amministrazione, senza chiamare una funzione. La maggior parte degli autori di plug-in sceglie di inserire il codice generatore di pagina in una funzione all'interno del file del plug-in principale. Nel caso in cui sia specificato il parametro della funzione, è possibile utilizzare qualsiasi stringa per il parametro del file. Ciò consente l'utilizzo di pagine come? Page = my_super_plugin_page anziché? Page = my-super-plugin / admin-options.php.

Quindi quello che posso ricavare da questo è che se lasci la funzione vuota cerca di includere un file php basato su ciò che hai impostato menu_slugsu.

MODIFICA 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 Lo so, e la funzione "load_view" funziona bene e produce correttamente il contenuto quando si utilizza un valore statico. Ad esempio: incl .... / views / my-panel.php ');
Luis

@Luis - Qual è il problema?
Brady,

@Brady array (& $ this, 'load_view') // Dove posso specificare il valore di $ nomefile ??. Non riesco a fare qualcosa come array (& $ this, 'load_view ("my-value")') Voglio trovare un modo per passare i parametri alla funzione che sto chiamando
Luis

Oh ho capito adesso. Vuoi passare una funzione di classe ma con un parametro. Bene, io ho guardato e guardato e non riesco a trovare il modo in cui lo fai. Ma dal momento che stai passando la classe, allora non puoi fare quello che ho messo in EDIT 2?
Brady,

@Brady: la tua seconda modifica non sarà di grande aiuto, devi solo sostituire la filenamevariabile, così sarà sempre "somethingelse". La tua prima modifica potrebbe essere il trucco qui: se load_viewnon fa altro che includere il file, non dovresti davvero passare una funzione di callback e WordPress proverà a caricare la pagina che hai passato come slug.
Jan Fabry,

0

Ho risolto questo problema semplicemente aggiungendo l'ID (o qualsiasi altro dato necessario) alla barra dei menu.

Per esempio:

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

Questo creerà quindi un URL con 'my-plugin-settings-nomefile' (come esempio), e posso semplicemente analizzare quella parte dell'URL (con $ _GET o filter_input).


Puoi anche utilizzare un parametro URL, ma devi creare una voce di menu (e quindi puoi nasconderla se lo desideri).
Jeff Vdovjak,

Grazie per aver inserito il mio codice in un blocco di codice toscho. Quando faccio una domanda c'è un pulsante, ma non ho familiarità con il markup per farlo in una risposta.
Jeff Vdovjak,

0

Sulla base della risposta user35752 , è anche possibile utilizzare un metodo oggetto con parametri come callback.

$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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.