Come passare argomenti a una callback di pagina menu admin in WordPress?

5 mag 2011, 12:47:47
Visualizzazioni: 19K
Voti: 17

Situazione: Sto lavorando a un plugin e lo sto sviluppando come una classe. Tutto funzionava bene finché non mi sono imbattuto in questa situazione. Volevo rendere il codice più pulito e ho provato questo approccio..

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

    // Non voglio scrivere una funzione per ogni pagina di opzioni che creo
    // preferisco caricare il contenuto da un file esterno.        
    function load_view($filename) {
        $view = require(dirname(__FILE__).'/views/'.$filename.'.php');
        return $view;
    }

    // Qui sorge il problema
    function myplugin_create_menus() {
        add_menu_page( 'Nome plugin',
                       'Nome plugin',
                       'manage_options',
                       'my-plugin-settings',
                       array(&$this, 'load_view') // Dove posso specificare il valore di $filename??
                     );
    }

}#fine della classe

Ho provato diverse opzioni ma nulla funziona, forse la soluzione è davanti a me ma non la vedo.

Naturalmente questo è un esempio ricreato, ho prefissato tutte le mie funzioni e non sono esattamente come le ho scritte qui ma spero abbiate capito cosa sto chiedendo.

Grazie in anticipo.

P.S.: Se volete vedere il codice sorgente originale sarò felice di incollarlo e darvi il link.

0
Tutte le risposte alla domanda 5
2
10

Non puoi passare un argomento alla funzione di callback. add_menu_page() la aggiunge come gestore di azione, e admin.php attiva l'azione, senza alcun argomento.

Vedo due semplici soluzioni a questo problema. Una è memorizzare tutti i nomi dei file in un array nella tua classe, indicizzati per nome dell'hook. Poi puoi usarlo per cercare quale file devi caricare (puoi anche memorizzare dati aggiuntivi in questo array).

class WPSE16415_Plugin
{
    protected $views = array();

    function load_view() {
        // current_filter() restituisce anche l'azione corrente  
        $current_views = $this->views[current_filter()];
        include(dirname(__FILE__).'/views/'.$current_views.'.php');
    }

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

L'altra è saltare l'argomento della callback, così WordPress includerà il file indicato dal nome dello slug stesso, come suggerisce Brady nella sua risposta.

5 mag 2011 16:05:49
Commenti

ah-ha perché non ho pensato di farlo in quel modo :(

Scott Scott
5 mag 2011 19:00:29

SÌ!! hai salvato dozzine di gattini oggi... non avevo mai sentito parlare di quella funzione 'current_filter'. Soluzione molto intelligente. Grazie mille per il tuo aiuto @Brady @Jan Fabry

Luis Luis
5 mag 2011 19:39:17
5

Puoi sempre utilizzare una funzione anonima (o chiusura). Qualcosa del tipo:

add_menu_page( $page, $menu, $capability, $slug, function() { print_my_admin_page($with_args); }, $icon, $position);
25 lug 2013 03:24:02
Commenti

Non funziona per me. Sto usando WordPress 4.1 (e al giorno d'oggi 4.1.1)

Jeff Vdovjak Jeff Vdovjak
19 feb 2015 22:35:27

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

Quinn Comendant Quinn Comendant
15 mag 2015 07:35:33

Avrei dovuto specificare che quando si passano variabili nell'ambito di una funzione anonima, bisogna usare la parola chiave "use". function() use ($my_var) { // ora puoi usare $my_var }

user35752 user35752
27 mag 2015 05:34:36

Posso confermare che funziona perfettamente in WordPress v5.5

factorypolaris factorypolaris
16 ott 2020 12:19:19

Non funziona per me in WP 6.3.2

rank rank
19 ott 2023 13:53:26
3

Ho risolto questo problema semplicemente aggiungendo l'ID (o qualsiasi altro dato ti serva) allo slug del menu.

Per esempio:

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

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

19 feb 2015 06:43:15
Commenti

Potresti anche utilizzare un parametro URL, ma devi creare una voce di menu (e poi puoi nasconderla se lo desideri).

Jeff Vdovjak Jeff Vdovjak
19 feb 2015 22:33:50

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

Jeff Vdovjak Jeff Vdovjak
19 feb 2015 22:36:19

Questa è un'ottima idea per risolvere il problema.

rank rank
19 ott 2023 13:52:57
6

la funzione load_view dovrebbe essere così?:

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

e nel tuo file include dovrebbe stampare qualsiasi contenuto per la pagina visualizzata.

MODIFICA:

Ecco cosa dice il codex sull'argomento:

$menu_slug (string) (obbligatorio) Il nome slug per riferirsi a questo menu (deve essere univoco per questo menu). Prima della versione 3.0 questo parametro era chiamato file (o handle). Se il parametro funzione è 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 il menu. Tecnicamente, il parametro funzione è opzionale, ma se non viene fornito, WordPress assumerà sostanzialmente che includendo il file PHP verrà generata la schermata di amministrazione, senza chiamare una funzione. La maggior parte degli autori di plugin sceglie di inserire il codice generatore della pagina in una funzione all'interno del loro file plugin principale.:Nel caso in cui sia specificato il parametro funzione, è possibile utilizzare qualsiasi stringa per il parametro file. Ciò consente l'utilizzo di pagine come ?page=my_super_plugin_page invece di ?page=my-super-plugin/admin-options.php.

Quindi quello che posso dedurre da questo è che se lasci la funzione vuota, tenta di includere un file php basato su ciò che hai impostato come menu_slug.

MODIFICA 2

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

function myplugin_create_menus() {
    $this->filename = "something";
    add_menu_page( 'Nome plugin',
                   'Nome plugin',
                   'manage_options',
                   'my-plugin-settings',
                   array(&$this, 'load_view')
                 );
    $this->filename = "somethingelse";
    add_menu_page( 'Nome plugin',
                   'Nome plugin',
                   'manage_options',
                   'my-plugin-settings',
                   array(&$this, 'load_view')
                 );
}
5 mag 2011 13:47:59
Commenti

@Brady Lo so, e la funzione "load_view" funziona bene e restituisce il contenuto correttamente quando si utilizza un valore statico. Ad esempio: incl..../views/my-panel.php');

Luis Luis
5 mag 2011 13:57:38

@Luis - Allora qual è il problema?

Scott Scott
5 mag 2011 13:59:49

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

Luis Luis
5 mag 2011 14:31:04

Ah, ora ho capito. Vuoi passare una funzione di classe ma con un parametro. Ho cercato e cercato ma non riesco a trovare come si fa. Ma visto che stai passando la classe, non puoi fare come ho scritto in EDIT 2?

Scott Scott
5 mag 2011 15:06:37

@Brady: La tua seconda modifica non aiuterà molto, stai semplicemente sovrascrivendo la variabile filename quindi sarà sempre "qualcosaltro". La tua prima modifica potrebbe essere la soluzione qui: se load_view non fa altro che includere il file, dovresti infatti non passare una funzione callback e WordPress proverà a caricare la pagina che hai passato come slug.

Jan Fabry Jan Fabry
5 mag 2011 15:48:59

@Brady prima di tutto grazie per i tuoi sforzi :). Ho provato anche quello (edit 2) ma come ha detto @Jan Fabry ottengo l'ultimo valore impostato per tutti.

Luis Luis
5 mag 2011 18:35:41
Mostra i restanti 1 commenti
0

Basandoti sulla risposta di user35752, puoi anche utilizzare un metodo di un 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)
15 gen 2020 15:21:25