michaeluno / admin-page-framework

Facilitates WordPress plugin and theme development.
http://admin-page-framework.michaeluno.jp/
Other
337 stars 71 forks source link

Adding sub-menu pages to the top-level page in a separate script. #223

Closed ivandotv closed 8 years ago

ivandotv commented 8 years ago

I've read the FAQ , and your answer is: "In the setUp() method of MyAdminPageClasB, pass the instantiated class name of the main plugin that created the root menu, MyAdminPageClassA, to the setRootMenuPageBySlug() method." I don't know if this is currently complicated to implement , but you should really consider using hooks for this kind of stuff. In the scenario where a plugin creates the page, and a theme needs to add some options that are specific to the theme, you need to jump through hoops to do it.

michaeluno commented 8 years ago

There are a bunch of hooks already and I guess you can use the set_up_{class name} action hook to add sub-menu pages.

Try this code. This adds a sub-menu page to the loader plugin admin menu.

class APFTest_AddSubMenuPageToLoaderMenu {

    public $sPageSlug = 'apftest_add_submenu_page';

    /**
     * Sets up hooks.
     */
    public function __construct() {

        add_action( 'set_up_' . 'AdminPageFrameworkLoader_AdminPage', array( $this, 'replyToAddSubMenuPages' ) );

        add_action( 'load_' . $this->sPageSlug, array( $this, 'replyToChangePageSettings' ) );

        add_filter( 'content_' . $this->sPageSlug, array( $this, 'replyToModifyPageContents' ) );

    }

    /**
     * @callback    action      set_up_{class name}
     * @return      void
     */
    public function replyToAddSubMenuPages( $oFactory ) {

        $oFactory->addSubMenuPage(
            array(
                'page_slug' => $this->sPageSlug,
                'title'     => __( 'Example', 'your-text-domain' ),
                'order'     => 20,
            )        
        );

    }

    /**
     * Called when the page loads.
     * @callback    action      load_{page slug}
     * @return      void
     */
    public function replyToChangePageSettings( $oFactory ) {

        // enable/disable the page title of a specific page.
        $oFactory->setPageTitleVisibility( true ); 

    }

    /**
     * @callback    filter      content_{page slug}
     * @return      string
     */
    public function replyToModifyPageContents( $sContent ) {

        return $sContent
            . '<p>'
                . __( 'Hi there!', 'your-text-domain' )
            . '</p>';

    }

}
new APFTest_AddSubMenuPageToLoaderMenu;
ivandotv commented 8 years ago

The problem with the current setup of the framework is that action hooks are depended on the classnames. So I have done a little bit of experimenting and created other classes that extend AdminPageFramework and they are responding to creating the root page via action hook iki_set_root_menu_page{pageLabel} Those other classes are crating sub pages , and some other classes are creating options for those pages/tabs.

class iki_AbstractAdminPage extends AdminPageFramework {

    protected $rootLabel;

    protected function prepareId( $s ) {
        return strtolower( trim( preg_replace( '/[\s-]/', '_', $s ) ) );
    }

    public function setRootMenuPage( $sRootMenuLabel, $sIcon16x16 = null, $iMenuPosition = null ) {
        parent::setRootMenuPage( $sRootMenuLabel, $sIcon16x16, $iMenuPosition );
        $this->rootLabel = $this->prepareId( $sRootMenuLabel );
        do_action( 'iki_set_root_menu_page_' . $this->rootLabel, $this );
    }
}

What I'm trying to achieve is to be able to inject other submenu items, tabs, and option elements at particular steps in page creation process. I need to be able to inject submenu page from plugin when the parent page is created by the theme and vice versa. I'm tryin to do that also with other option elements, so if a theme has a page with options, some plugin should be able to add other option elements to that page, or particular tab on that page.

michaeluno commented 8 years ago

You did an interesting customization. I predict one problem in your customization that if the set label gets translated and includes unicode strings, your hook may not work.

Regarding injecting page elements from a separate script, I think the snippet I posted in the previous reply will let you do that. Also there are filter hooks for definitions of pages, in-page tabs, and form section and fields. Hooks are listed here.

The problem with the current setup of the framework is that action hooks are depended on the classnames.

I'm not sure. If you think it is a problem, can you create a new topic about it? Thank you.