1

I've started creating a WP plugin which should work only in Admin Area.

I've managed to create top-level menu with required sub-menu items, but when I try to print content of my page, it prints it twice, in a global scope of Admin panel and inside the page itself.

Main plugin file loads menu settings and separate page classes: require_once('settings.php');

require_once('pages/VmSettingsPage.php');
require_once('pages/VmTradersPage.php');

$settingsPage = new VmSettingsPage();
$tradersPage = new VmTradersPage();

Menu settings:

add_action('admin_menu', 'cvmAdminMenu');
function cvmAdminMenu() {
    add_menu_page('VM Tool', 'VM Tool',
        'manage_options', 'camden-vmtool', ['VmSettingsPage','pageInit']);

    add_submenu_page('camden-vmtool', 'Traders Pages', 'Traders Pages', 'manage_options',
        'camden-vmtool-traders', ['VmTradersPage','pageInit']);
    add_submenu_page('camden-vmtool', 'Style Pages', 'Style Pages', 'manage_options',
        'camden-vmtool-style', 'cvmRenderStyle');
    add_submenu_page('camden-vmtool', 'Cat Navs', 'Cat Navs', 'manage_options',
        'camden-vmtool-cat-navs', 'cvmRenderCatnavs');
}

Settings Page class:

<?php

class VmSettingsPage {
    private $options;

    public function __construct()
    {
        add_action('admin_init', [$this, 'pageInit']);
    }

    public function pageInit() {
        echo 23123;
    }
}

Question #1 - The above code will output 23123 twice, when visiting plugin page and when not. How do I make it print the content of my page only when page is the current screen? Basically: http://localhost/wp-admin/admin.php?page=camden-vmtool

Question #2 - How to preload only one page class based on currently opened page? I will have around 4 pages, and It feels bad to load classes at once, just to have the class instance initiated.

BTW, get_current_screen's base parameter != $_GET['page'], so I cannot even match those to print correct content.

Check the output

Thanks

1 Answer 1

0

Question #1 - The above code will output 23123 twice, when visiting plugin page and when not. How do I make it print the content of my page only when page is the current screen? Basically: http://localhost/wp-admin/admin.php?page=camden-vmtool

When you initialize the class, you are hooking the pageInit() method into a hook that fires on all admin pages. You are then specifically calling that method in your add_menu_page() arguments.

Honestly, I don't understand this one:

Question #2 - How to preload only one page class based on currently opened page? I will have around 4 pages, and It feels bad to load classes at once, just to have the class instance initiated.

As to the first question, I don't know what PageInit() needs to do but given the limited information there is no need to instantiate the class beforehand. This works as is:

class VmSettingsPage {
    private $options;

    public function __construct()
    {
        add_action('admin_init', array($this, 'pageInit'));
    }

    public function pageInit() {
        echo 23123;
    }
}
// $settingsPage = new VmSettingsPage();

add_action('admin_menu', 'cvmAdminMenu');
function cvmAdminMenu() {
    add_menu_page('VM Tool', 'VM Tool',
        'manage_options', 'camden-vmtool', array('VmSettingsPage','pageInit'));

}

The class will be instantiated automatically. If you do need to instantiate the class then your callback should be different:

class VmSettingsPage {
    private $options;

    public function __construct()
    {
//         add_action('admin_init', array($this, 'pageInit'));
    }

    public function pageInit() {
        echo 23123;
    }
}
global $settingsPage;
$settingsPage = new VmSettingsPage();

add_action('admin_menu', 'cvmAdminMenu');
function cvmAdminMenu() {
  global $settingsPage;
    add_menu_page('VM Tool', 'VM Tool',
        'manage_options', 'camden-vmtool', array($settingsPage,'pageInit'));
}

If you do that, then you can't use admin_init but there is no apparent reason to use that admin_init hook at all anyway.

I would further suggest that you encapsulate everything into your class:

class VmSettingsPage {
    private $options;

    public function __construct()
    {
//         add_action('admin_init', array($this, 'pageInit'));
      add_action('admin_menu', array($this,'cvmAdminMenu'));

    }

    function cvmAdminMenu() {
        add_menu_page('VM Tool', 'VM Tool',
            'manage_options', 'camden-vmtool', array($this,'pageInit'));
    }

    public function pageInit() {
        echo 23123;
    }
}
$settingsPage = new VmSettingsPage();
1
  • Thanks a lot, that did the job for Question #1. As for the #2, I just wanted to eliminate the need to require_once all 4 page classes at once (so they can be instantiated), instead I wanted to require only one class that is needed for the page I'm looking at Commented Jun 13, 2015 at 15:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.