Передача аргументів до зворотного виклику сторінки меню адміністратора?


14

Ситуація: я працюю над плагіном і розвиваю його як клас, все спрацювало нормально, поки я не зіткнувся з цією ситуацією. Я хотів зробити речі трохи чистішими і спробував це.

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

Я спробував купу різних варіантів, але нічого не працює, можливо, я перед цим, але не можу його побачити.

Звичайно, це відтворення, я встановив всі свої функції, і вони не є такими, як я написав тут, але, сподіваюся, ви зрозуміли, про що я прошу.

Заздалегідь спасибі.

ПД: Якщо ви хочете побачити оригінальний вихідний код, я буду радий вставити його та надати вам посилання.

Відповіді:


8

Ви не можете передавати аргумент функції зворотного дзвінка. add_menu_page()додає його як обробник дії та admin.phpзапускає дію без будь-яких аргументів.

Я бачу два простих рішення цієї проблеми. Перший - це збереження всіх імен файлів у масиві у вашому класі, індексованих іменем гачка. Потім ви можете використовувати це для пошуку файлу, який потрібно завантажити (ви також можете зберігати додаткові дані в цьому масиві).

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

Інше - пропустити аргумент зворотного виклику, тому WordPress включить файл, вказаний самим ім'ям слизи, як пропонує Брейді у своїй відповіді.


а-ха, чому я не думав робити це саме так :(
Брейді

ТАК !! Ви врятували десятки кошенят сьогодні .. ніколи не чули про цю функцію, хоча "current_filter". Дуже розумне рішення. Дякую за допомогу @Brady @Jan Fabry
Luis

4

Ви завжди могли просто використовувати анонімну функцію (або закриття). Щось, на що впливає:

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

1
Це не працює для мене. Я використовую WordPress 4.1 (а станом на сьогодні 4.1.1)
Jeff Vdovjak

Розумний! І це працює. Ось більш повний приклад: hastebin.com/segibugice, який створив би URL-адресу, наприклад example.com/wp-admin/admin.php?page=my-slug
Квінн Комендант

Я повинен був би згадати, передаючи змінні в область анонімної функції, ви повинні використовувати ключове слово "використовувати". function() use ($my_var) { // now you can use $my_var }
користувач35752

0

функція load_view повинна бути такою ?:

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

і у вашому файлі включення він повинен відповідати будь-якому вмісту сторінки, що відображається.

Редагувати:

Ось що в цьому питанні говорить кодекс:

$menu_slug (string) (required)Ім'я слизи для посилання на це меню (має бути унікальним для цього меню). До версії 3.0 це називалося параметром файлу (або обробляти). Якщо параметр функції опущено, у меню_slug повинен бути файл PHP, який обробляє відображення вмісту сторінки меню. За замовчуванням: Ні

$function Функція, яка відображає вміст сторінки для сторінки меню. Технічно параметр функції необов’язковий, але якщо він не надається, то WordPress в основному передбачає, що включення файлу PHP генерує екран адміністрування без виклику функції. Більшість авторів плагінів вирішили поставити код, що генерує сторінку, у функцію в межах свого основного файла плагінів. Це дозволяє використовувати такі сторінки, як? Page = my_super_plugin_page замість? Page = my-super-plugin / admin-options.php.

Тож, з чого я можу зібратись, це те, що якщо ви залишаєте функцію порожньою, вона намагається включити файл php на основі того, що ви встановили menu_slug.

EDIT 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 Я знаю це, і функція "load_view" працює добре і виводить вміст правильно при використанні статичного значення. Наприклад: incl .... / views / my-panel.php ');
Луїс

@Luis - Тоді в чому проблема?
Брейді

@Brady масив (& $ this, 'load_view') // Де я можу вказати значення $ filename ??. Я не можу зробити щось на зразок масиву (& $ this, 'load_view ("my-value")') Я хочу знайти спосіб передачі параметрів функції, яку я дзвоню
Луїс

О, я зрозумію це зараз. Ви хочете передати функцію класу, але з параметром. Ну, я виглядав і дивився, і не можу знайти, як ти це робиш. Але оскільки ви проходите клас, то чи не можете ви зробити те, що я вклав у EDIT 2?
Брейді

@Brady: Ваша друга редакція не дуже допоможе, ви просто перекриєте filenameзмінну, щоб вона завжди була "somethingelse". Ваша перша редакція тут може бути хитрістю: якщо load_viewнічого не стосується, крім включення файлу, ви дійсно не повинні передавати функцію зворотного дзвінка, і WordPress спробує завантажити сторінку, яку ви пройшли як слизьку.
Ян Фабрі

0

Я вирішив цю проблему, просто додавши ідентифікатор (або будь-які дані, що вам потрібні) до меню.

Наприклад:

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

Потім буде створено URL-адресу з "my-plugin-settings-filename" (як приклад), і я можу просто проаналізувати цю частину URL-адреси (за допомогою $ _GET або filter_input).


Ви також можете використовувати параметр URL-адреси, але вам потрібно створити пункт меню (а потім приховати його, якщо хочете).
Джефф Вдовик

Дякуємо, що помістили мій код у блок коду toscho. Коли я задаю питання, є кнопка, але я не знайомий з розміткою, щоб зробити це у відповіді.
Джефф Вдовик

0

На основі відповіді user35752 ви навіть можете використовувати метод об'єкта з парами як зворотний виклик.

$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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.