Come passare argomenti a una callback di pagina menu admin in WordPress?
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.

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.

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

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

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 }

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).

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

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.

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

@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');

@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

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?

@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.

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)
