Cum să pasezi argumente la un callback pentru pagina de meniu în admin WordPress?

5 mai 2011, 12:47:47
Vizualizări: 19K
Voturi: 17

Situație: Lucrez la un plugin și îl dezvolt ca o clasă, totul a funcționat bine până am dat peste această situație. Am vrut să fac lucrurile mai clare și am încercat asta..

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

    //Nu vreau să scriu o funcție pentru fiecare pagină de opțiuni pe care o creez
    //așa că prefer să încărc conținutul dintr-un fișier extern.        
    function load_view($filename) {
        $view = require(dirname(__FILE__).'/views/'.$filename.'.php');
        return $view;
    }

    //Aici apare problema
    function myplugin_create_menus() {
        add_menu_page( 'Nume plugin',
                       'Nume plugin',
                       'manage_options',
                       'my-plugin-settings',
                       array(&$this, 'load_view') // Unde specific valoarea pentru $filename??
                     );
    }

}#sfârșitul clasei

Am încercat mai multe variante dar nimic nu funcționează, poate sunt chiar în fața soluției dar nu o văd.

Desigur, acesta este un exemplu recreat, am folosit prefixe pentru toate funcțiile și nu sunt exact cum le-am scris aici dar sper că înțelegeți ideea.

Mulțumesc anticipat.

P.S.: Dacă doriți să vedeți codul sursă original, pot să-l postez și să vă dau link-ul.

0
Toate răspunsurile la întrebare 5
2
10

Nu poți pasa un argument funcției de callback. add_menu_page() o adaugă ca un handler de acțiune, iar admin.php declanșează acțiunea, fără niciun argument.

Văd două soluții simple la această problemă. Una este să stochezi toate numele de fișiere într-un array în clasa ta, indexate după numele hook-ului. Apoi poți folosi acest array pentru a căuta fișierul pe care trebuie să-l încarci (poți stoca și alte date suplimentare în acest array).

class WPSE16415_Plugin
{
    protected $views = array();

    function load_view() {
        // current_filter() returnează și acțiunea curentă
        $current_views = $this->views[current_filter()];
        include(dirname(__FILE__).'/views/'.$current_views.'.php');
    }

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

Cea de-a doua soluție este să omiți argumentul callback, astfel încât WordPress va include fișierul indicat de numele slug-ului în sine, așa cum sugerează Brady în răspunsul său.

5 mai 2011 16:05:49
Comentarii

ah-ha de ce nu m-am gândit să fac așa :(

Scott Scott
5 mai 2011 19:00:29

DAAAA!! ai salvat zeci de pisoi astăzi.. nu auzisem niciodată de acea funcție 'current_filter'. Soluție foarte inteligentă. Mulțumesc mult pentru ajutor @Brady @Jan Fabry

Luis Luis
5 mai 2011 19:39:17
5

Puteți folosi întotdeauna o funcție anonimă (sau closure). Ceva de genul:

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

Nu funcționează pentru mine. Folosesc WordPress 4.1 (și de astăzi 4.1.1)

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

Inteligent! Și chiar funcționează. Iată un exemplu mai complet: http://hastebin.com/segibugice care ar genera un URL precum http://example.com/wp-admin/admin.php?page=my-slug

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

Trebuia să menționez că atunci când transmiți variabile în scopul unei funcții anonime, trebuie să folosești cuvântul cheie "use". function() use ($my_var) { // acum poți folosi $my_var }

user35752 user35752
27 mai 2015 05:34:36

Pot confirma că funcționează perfect în WordPress v5.5

factorypolaris factorypolaris
16 oct. 2020 12:19:19

Nu funcționează pentru mine în WP 6.3.2

rank rank
19 oct. 2023 13:53:26
3

Am rezolvat această problemă prin simpla adăugare a ID-ului (sau orice altă dată de care ai nevoie) la slug-ul meniului.

De exemplu:

 add_menu_page( 'Nume plugin',
                       'Nume plugin',
                       'manage_options',
                       'setări-plugin-meu-' . $identifier,
                       'funcție-callback-setări'
                     );

Aceasta va crea un URL cu 'setări-plugin-meu-nume-fisier' (ca exemplu), iar eu pot analiza acea parte a URL-ului (cu $_GET sau filter_input).

19 feb. 2015 06:43:15
Comentarii

Ai putea folosi și un parametru URL, dar trebuie să creezi un element de meniu (pe care îl poți ascunde ulterior dacă dorești).

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

Mulțumesc că ai pus codul meu într-un bloc de cod, toscho. Când pun o întrebare, există un buton pentru asta, dar nu sunt familiarizat cu markup-ul necesar pentru a face același lucru într-un răspuns.

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

Aceasta este o idee excelentă pentru rezolvarea problemei.

rank rank
19 oct. 2023 13:52:57
6

Funcția load_view ar trebui să arate astfel?:

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

iar în fișierul inclus ar trebui să afișezi orice conținut pentru pagina care este afișată.

EDIT:

Iată ce spune codex-ul pe această temă:

$menu_slug (string) (obligatoriu) Numele slug pentru a face referire la acest meniu (ar trebui să fie unic pentru acest meniu). Înainte de Versiunea 3.0 acesta se numea parametrul fișier (sau handle). Dacă parametrul funcției este omis, menu_slug ar trebui să fie fișierul PHP care gestionează afișarea conținutului paginii de meniu. Implicit: Niciunul

$function Funcția care afișează conținutul paginii pentru pagina de meniu. Tehnic, parametrul funcției este opțional, dar dacă nu este furnizat, atunci WordPress va presupune că includerea fișierului PHP va genera ecranul de administrare, fără a apela o funcție. Majoritatea autorilor de plugin-uri aleg să pună codul generatoare de pagină într-o funcție în fișierul principal al plugin-ului.: În cazul în care parametrul funcției este specificat, este posibil să folosești orice șir de caractere pentru parametrul fișier. Acest lucru permite utilizarea de pagini precum ?page=my_super_plugin_page în loc de ?page=my-super-plugin/admin-options.php.

Deci, din câte înțeleg, dacă lași funcția goală, acesta va încerca să includă un fișier php bazat pe ceea ce ai setat la menu_slug.

EDIT 2

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

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

@Brady Știu asta, iar funcția "load_view" funcționează corect și afișează conținutul așa cum trebuie când folosești o valoare statică. De exemplu: incl..../views/my-panel.php');

Luis Luis
5 mai 2011 13:57:38

@Luis - Atunci care este problema?

Scott Scott
5 mai 2011 13:59:49

@Brady array(&$this, 'load_view') // Unde specific valoarea pentru $filename??. Nu pot face ceva de genul array(&$this, 'load_view("my-value")') Vreau să găsesc o metodă de a pasa parametri către funcția pe care o apelez

Luis Luis
5 mai 2011 14:31:04

Ah, acum am înțeles. Vrei să transmiți o funcție de clasă dar cu un parametru. Ei bine, am căutat și căutat și nu pot găsi cum se face. Dar dacă transmiți clasa, atunci nu poți face ce am scris în EDIT 2?

Scott Scott
5 mai 2011 15:06:37

@Brady: A doua ta editare nu va ajuta prea mult, doar suprascrii variabila filename așa că va fi întotdeauna "altceva". Prima ta editare ar putea fi soluția aici: dacă load_view nu face altceva decât să includă fișierul, atunci într-adevăr nu ar trebui să transmiți o funcție callback și WordPress va încerca să încarce pagina pe care ai transmis-o ca slug.

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

@Brady în primul rând mulțumesc pentru eforturile tale :). Am încercat și eu asta (editarea 2) dar cum a spus @Jan Fabry, primesc ultima valoare setată pentru toate.

Luis Luis
5 mai 2011 18:35:41
Arată celelalte 1 comentarii
0

Bazat pe răspunsul user35752, poți folosi chiar și o metodă a unui obiect cu parametri drept 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 ian. 2020 15:21:25