0

Context

I'm making a big plugin with a complex architecture. I would like in my plugin architecture split pages and menus building on admin side.

So I have these classes : Menu.php, Submenu.php and Page.php, SubPage.php

I would like, when the administrator clik on menu/submenu links, it runs a common function callback inside Menu.php and Submenu.php which load only the right page or subpage thanks $_GET['page'].

Problem

Each submenu link does not bind a subpage anymore.

All href of submenu links are in this format :

https://my-site.org/wp-admin/my-slug-page

instead of :

https://my-site.org/wp-admin/admin.php?page=my-slug-page

Submenu.php

class SubMenu { 

    public $parent_slug;

    public $page_title;

    public $menu_title;

    public $capability;

    public $menu_slug;

    public $priority;


   public function __construct( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $priority = 10 ) {
       $this->parent_slug = $parent_slug;
       $this->page_title = $page_title;
       $this->menu_title = $menu_title;
       $this->capability = $capability;
       $this->menu_slug = $menu_slug;
       $this->priority = $priority;

       // Initialize the component
       add_action( 'admin_menu', array( $this, 'add_submenu' ), $this->priority );
   }


   public function add_submenu() {

        $page_hook = add_submenu_page(
             $this->parent_slug, 
             _x( $this->page_title, "page_title", PLUGIN_DOMAIN ), 
             _x( $this->menu_title, "menu_title", PLUGIN_DOMAIN ), 
             $this->capability, 
             $this->menu_slug, 
             array( $this, "output_rooter" ) 
        );

   }

   public function output_rooter(){
        // check $_GET['page'] value
        ...
        // Load the right SubPage class with the view
        $class = strToKamelCase( $_GET['page'] );
        new $class(); //<-- extends SubPage.php
        ... 
   }



}

The function output_rooter is never called and I have a 404 error each time I click on a submenu link.

Notice : with menu links it works correctly and all href links are perfect.

Someone has got an idea what it should be ?

0

I found my solution.

Problem of hrefs

when the wordpress core did not find the function callback or it's empty for the functions add_menu_page() and add_submenu_page() the href wil be generated like this : http(s)://my-site.org/wp-admin/my-slug-page, otherwise the href is in this format : http(s)://my-site.org/wp-admin/admin.php?page=my-slug-page

So In my case, I had to be sure the functions callback are called.

Problem to bind the menus with page and load only the current page

I had to call a static public function in add_submenu_page() which is located inside my page classes.

  • Any page classes extends Page.php.

  • Any sub pages classes extends SubPage.php.

  • The static function to init any page/sub page is the same for all.

So I made PageTrait.php which is used in Page.php and SubPage.php.

This is the code :

SubMenu.php

class SubMenu { 

    public $parent_slug;

    public $page_title;

    public $menu_title;

    public $capability;

    public $menu_slug;

    protected $subpage_class; //<-- new argument used for the submenu function callbak

    public $priority;


    public function __construct( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $subpage_class, $priority = 10 ) {
         $this->parent_slug = $parent_slug;
         $this->page_title = $page_title;
         $this->menu_title = $menu_title;
         $this->capability = $capability;
         $this->menu_slug = $menu_slug;
         $this->subpage_class = $subpage_class;
         $this->priority = $priority;

         // Initialize the component
         add_action( 'admin_menu', array( $this, 'add_submenu' ), $this->priority );
    }


    public function add_submenu() {

         $page_hook = add_submenu_page(
             $this->parent_slug, 
             _x( $this->page_title, "page_title", PLUGIN_DOMAIN ), 
             _x( $this->menu_title, "menu_title", PLUGIN_DOMAIN ), 
             $this->capability, 
             $this->menu_slug, 
             array( $this->subpage_class, "init_page" ) 
         );

    }
}

PageTrait.php

trait PageTrait {

      public static function init_page(){
          //Code to init the right page
          //1.Get data for the constructor
          ...
          //2.Get the class path
          ...
          new $classPath( $data );
      }
}

Page.php

class Page {

    use PageTrait;
    ....
}

SubPage.php

class SubPage{

    use PageTrait;
    ....
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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