Extend Individual Menu on Page Function to individual Submenue on Page Function?

It seems that WordPress Development is building a knowledge-base about the best functions out there. Thanks a bunch this helped already a lot!

I found a function (find it down here) that offers a simple menu decision in a box for each page of your wordpress theme. A magic bag trick, kudos to H Peter Pfeufer!

but how does it work to just change the sub-header-menu in the sub-header-menu- theme position and not all menues on page with is nonsense.

As the function returns $args I wonder how to tell Wp that i just want them to change menu in sub-header-menu position. Do you have an idea or other Function, Would be big!

/**
 * Erstellt eine Meta Box um einer Seite ein eigenes Menü mit zu geben.
 * Die Menüs müssen unter Design -> Menü definiert sein.
 *
 * @author H.-Peter Pfeufer
 */
if(!class_exists('Page_Menu_Meta_Box')) {
    class Page_Menu_Meta_Box {
        private $textdomain = 'meine-textdomain';   // Textdomain für die Übersetzung
        private $posttype = 'page';                 // Posttype (hier page für Seiten)
        private $metaname = 'page_menu';            // Name des Custom Fields
        private $metaboxID = 'page_menu';           // ID der Metabox
        private $noncename = 'page_menu';           // Name des Nonce (etwas für die Sicherheit
        private $defaultmenu = 'default';           // "Slug" des Standardmenüs
        private $userright = 'edit_page';           // Nutzerrechte die benötigt werden
        private $selectname = 'page-menu';          // Name des Selectferldes

        /**
         * Constructor (old style)
         *
         * @uses __construct
         */
        function Page_Menu_Meta_Box() {
            self::__construct();
        } // END function Page_Menu_Meta_Box()

        /**
         * Constructor
         */
        function __construct() {
            // Backend
            if(is_admin()) {
                add_action('add_meta_boxes', array(
                    &$this,
                    '_add_meta_box'
                ));

                add_action('save_post', array(
                    &$this,
                    '_save_page_menu'
                ));
            } // END if(is_admin())

            // Frontend
            if(!is_admin()) {
                add_filter('wp_nav_menu_args', array(
                    &$this,
                    '_menu_per_page'
                ));
            } // END if(!is_admin())
        } // END function __construct()

        /**
         * Metabox am System anmelden
         */
        function _add_meta_box() {
            add_meta_box($this->metaboxID, __('Select the menu for this page', $this->textdomain), array(
                &$this,
                'the_meta_box'
            ), $this->posttype, 'normal', 'high');
        } // END function _add_meta_box()

        /**
         * Metabox erstellen
         */
        function the_meta_box() {
            global $post;

            // Menüs abholen
            $menues = wp_get_nav_menus();

            if(!empty($menues) && count($menues) != 0) {
                // Use nonce for verification
                wp_nonce_field(plugin_basename( __FILE__ ), $this->noncename);

                // Ist bereits ein Menü gewählt?
                $menuslug = get_post_meta($post->ID, $this->metaname, true);

                // Setting the defaultmenu
                if(empty($menuslug)) {
                    $menuslug = $this->defaultmenu;
                } // END if(empty($menu_name))

                echo sprintf('<p>%1$s</p>', __('Please select the menu which should be displayed on this page.', $this->textdomain));
                echo '<select name="' . $this->selectname . '">';

                foreach($menues as $menu) {
                    if(!empty($menuslug)) {
                        $selected = '';

                        if($menuslug == $menu->slug) {
                            $selected = ' selected="selected"';
                        } // END if($menu_name == $menu->slug)
                    } // END if(!empty($menu_name))

                    echo '<option value="' . $menu->slug . '"' . $selected . '>' . $menu->name . '</option>';
                } // END foreach($menues as $menu)

                echo '</select>';
            } // END if(!empty($menues) && count($menues) != 0)
        } // END function the_meta_box()

        /**
         * Daten speichern
         *
         * @param int $post_id
         */
        function _save_page_menu($post_id) {
            // Erst mal schauen wir, ob der Nutzer das überhaupt darf
            if(!current_user_can($this->userright, $post_id)) {
                return;
            }

            // Dann prüfen wir die Nonces
            if(!isset($_REQUEST[$this->noncename]) || !wp_verify_nonce($_REQUEST[$this->noncename], plugin_basename(__FILE__))) {
                return;
            } // END if(!isset($_REQUEST['vokabel_page_menu']) || !wp_verify_nonce($_REQUEST['vokabel_page_menu'], plugin_basename(__FILE__)))

            // und nun wird der ganze Hokuspokus gespeichert
            $post_id = $_REQUEST['post_ID'];

            // Metainformationen hinzufügen oder aktualisieren
            add_post_meta($post_id, $this->metaname, $_REQUEST[$this->selectname], true) or update_post_meta($post_id, $this->metaname, $_REQUEST[$this->selectname]);
        } // END function _save_page_menu($post_id)

        /**
         * Menü im Frontend anzeigen
         *
         * @param array $args
         * @return Ambigous <mixed, string, multitype:, boolean, array, string>
         */
        function _menu_per_page($args = '') {
            if(is_page()) {
                global $post;

                $menuslug = get_post_meta($post->ID, $this->metaname, true);

                if(!empty($menuslug) && is_nav_menu($menuslug)) {
                    $args['menu'] = $menuslug;
                } // END if(!empty($menu_name) && is_nav_menu($menu_name))
            } // END if(is_page())

            return $args;
        } // END function _menu_per_page($args = '')
    } // END class Page_Menu_Meta_Box

    // Klasse starten
    new Page_Menu_Meta_Box();

} // END if(!class_exists('Page_Menu_Meta_Box'))

Solutions

the solution is now included in a plug in!

    <?php
/**
 * Plugin Name: CE WP-Menu per Page
 * Plugin URI: http://ppfeufer.de/wordpress-plugin/ce-wp-menu-per-page/
 * Description: This plugin allows you to select a menu on a per page basis.
 * Version: 1.2
 * Author: Codeenterprise (H.-Peter Pfeufer)
 * Author URI: http://codeenterprise.de
 * Text Domain: ce-wp-menu-per-page
 * Domain Path: /l10n
 */


        /**
         * Constructor (old style)
         *
         * @uses __construct
         */
        function Ce_Wp_Menu_Per_Page() {
            self::__construct();
        } // END function Ce_Wp_Menu_Per_Page()

        /**
         * Constructor
         */
        function __construct() {
            // Backend
            if(is_admin()) {
                add_action('admin_init', array(
                    $this,
                    '_plugin_init'
                ));

                add_action('add_meta_boxes', array(
                    $this,
                    '_add_meta_box'
                ));

                add_action('save_post', array(
                    $this,
                    '_save_page_menu'
                ));
            } // END if(is_admin())

            // Frontend
            if(!is_admin()) {
                add_filter('wp_nav_menu_args', array(
                    $this,
                    '_menu_per_page'
                ));
            } // END if(!is_admin())
        } // END function __construct()

        function _plugin_init() {
            /**
             * Sprachdatei wählen
             */
            if(function_exists('load_plugin_textdomain')) {
                load_plugin_textdomain($this->textdomain, false, dirname(plugin_basename( __FILE__ )) . '/l10n/');
            } // END if(function_exists('load_plugin_textdomain'))
        } // END function _plugin_init()

        /**
         * Metabox am System anmelden
         */
        function _add_meta_box() {
            add_meta_box($this->metaboxID, __('Select the menu for this page', $this->textdomain), array(
                $this,
                'the_meta_box'
            ), $this->posttype, 'normal', 'high');
        } // END function _add_meta_box()

        /**
         * Metabox erstellen
         */
        function the_meta_box() {
            global $post;

            // Menüs abholen
            $menues = wp_get_nav_menus();
            $menu_locations = get_registered_nav_menus();

            if(!empty($menues) && count($menues) != 0) {
                // Use nonce for verification
                wp_nonce_field(plugin_basename( __FILE__ ), $this->noncename);

                // Ist bereits ein Menü gewählt?
                $menuslug = get_post_meta($post->ID, $this->metaname_menu, true);
                $menuposition = get_post_meta($post->ID, $this->metaname_menu_position, true);

                // Setting the defaultmenu
                if(empty($menuslug)) {
                    $menuslug = $this->defaultmenu;
                } // END if(empty($menu_name))

                $array_DefaultMenu['wp-default'] = new stdClass();
                $array_DefaultMenu['wp-default']->name = __('Wordpress Default', $this->textdomain);
                $array_DefaultMenu['wp-default']->slug = 'wp-default';

                $menues = array_merge($array_DefaultMenu, (array) $menues);

                echo sprintf('<p>%1$s</p>', __('Please select the menu which should be displayed on this page.', $this->textdomain));
                echo '<select name="' . $this->menu_selectname . '">';

                foreach($menues as $menu) {
                    if(!empty($menuslug)) {
                        $selected = '';

                        if($menuslug == $menu->slug) {
                            $selected = ' selected="selected"';
                        } // END if($menu_name == $menu->slug)
                    } // END if(!empty($menu_name))

                    echo '<option value="' . $menu->slug . '"' . $selected . '>' . $menu->name . '</option>';
                } // END foreach($menues as $menu)

                echo '</select>';

                if(is_array($menu_locations) && count($menu_locations) != 0) {
                    echo sprintf('<p>%1$s</p>', __('Please select the menu location, where your menu should appear', $this->textdomain));
                    echo '<select name="' . $this->position_selectname . '">';

                    foreach($menu_locations as $slug => $position) {
                        if(!empty($menuposition)) {
                            $selected = '';

                            if($menuposition == $slug) {
                                $selected = ' selected="selected"';
                            } // END if($menu_name == $menu->slug)
                        } // END if(!empty($menu_name))

                        echo '<option value="' . $slug . '"' . $selected . '>' . $position . '</option>';
                    } // END foreach($menues as $menu)

                    echo '</select>';
                } // END if(is_array($menu_locations) && count($menu_locations) != 0)
            } // END if(!empty($menues) && count($menues) != 0)
        } // END function the_meta_box()

        /**
         * Daten speichern
         *
         * @param int $post_id
         */
        function _save_page_menu($post_id) {
            // Erst mal schauen wir, ob der Nutzer das überhaupt darf
            if(!current_user_can($this->userright, $post_id)) {
                return;
            }

            // Dann prüfen wir die Nonces
            if(!isset($_REQUEST[$this->noncename]) || !wp_verify_nonce($_REQUEST[$this->noncename], plugin_basename(__FILE__))) {
                return;
            } // END if(!isset($_REQUEST['vokabel_page_menu']) || !wp_verify_nonce($_REQUEST['vokabel_page_menu'], plugin_basename(__FILE__)))

            // und nun wird der ganze Hokuspokus gespeichert
            $post_id = $_REQUEST['post_ID'];

            /**
             * Saving the Settings
             */
            if($_REQUEST[$this->menu_selectname] == $this->defaultmenu) {
                // Get the old slug
                $menuslug = get_post_meta($post->ID, $this->metaname_menu, true);

                if(empty($menuslug)) {
                    delete_post_meta($post_id, $this->metaname_menu);
                    delete_post_meta($post_id, $this->metaname_menu_position);
                } // END if(empty($menu_name))
            } else {
                // Metainformationen hinzufügen oder aktualisieren
                add_post_meta($post_id, $this->metaname_menu, $_REQUEST[$this->menu_selectname], true) or update_post_meta($post_id, $this->metaname_menu, $_REQUEST[$this->menu_selectname]);
                add_post_meta($post_id, $this->metaname_menu_position, $_REQUEST[$this->position_selectname], true) or update_post_meta($post_id, $this->metaname_menu_position, $_REQUEST[$this->position_selectname]);
            } // END // END if($_REQUEST[$this->menu_selectname] == $this->defaultmenu)
        } // END function _save_page_menu($post_id)

        /**
         * Menü im Frontend anzeigen
         *
         * @param array $args
         * @return Ambigous <mixed, string, multitype:, boolean, array, string>
         */
        function _menu_per_page($args = '') {
            global $post;

            if(!empty($post)) {
                $menuslug = get_post_meta($post->ID, $this->metaname_menu, true);
                $menuposition = get_post_meta($post->ID, $this->metaname_menu_position, true);

                if(empty($menuposition)) {
                    $menuposition = $this->defaultmenu_position;
                } // END if(empty($menuposition))

                if(is_page() && $args['theme_location'] == $menuposition) {
                    if(!empty($menuslug) && is_nav_menu($menuslug)) {
                        $args['menu'] = $menuslug;
                    } // END if(!empty($menu_name) && is_nav_menu($menu_name))
                } // END if(is_page())
            } // END if(!empty($post))

            return $args;
        } // END function _menu_per_page($args = '')
    } // END class Ce_Wp_Menu_Per_Page

    // Klasse starten
    new Ce_Wp_Menu_Per_Page();
} // END if(!class_exists('Ce_Wp_Menu_Per_Page'))

If this is about specifying your $theme_location for wp_nav_menu() , than it should be enough to check if it is the right location. And only than modify the $args of the _menu_per_page() function, which is used as callback for the wp_nav_menu_args filter. So the function looks like this:

    function _menu_per_page( $args ) {
        if(is_page()) {
            // the selected menu applies to the following location
            if ( $args['theme_location'] == 'sub-header-menu' ) {
                global $post;

                $menuslug = get_post_meta($post->ID, $this->metaname, true);

                if(!empty($menuslug) && is_nav_menu($menuslug)) {
                    $args['menu'] = $menuslug;
                } // END if(!empty($menu_name) && is_nav_menu($menu_name))
            } // END if ( $args['theme_location'] == 'sub-header-menu' )
        } // END if(is_page())

        return $args;
    } // END function _menu_per_page($args = '')
Tags: Menus

Similar questions

Overwrite or extend Wordpress Function » wp_html_excerpt
how can i change (overwrite, extend) the wordpress function "wp_html_excerpt()" with my own function? It doesnt work with: Thank you in advance * update * i try to remove these tags: [emoji]...[/emoji] from my excerpt output
Trying to extend a Wordpress plugin, need to hook a function
I am trying to add some site-specific functionality to the Wordpress plugin Appointments+. When a user is making an appointment, they select certain services and enter information into some fields for confirmation. What I want to do is add some code so the extra information fields are related to which service they choose. For example, if they choos...
Override the WooCommerce function to extend category list design
I have done a change in the class-wc-product-cat-list-walker.php file and following is the changes in the code I want to keep it in the child theme and make it functional. Is there any way? I have tried to copy the file and paste it in the child theme WooCommerce folder. but it is not working. please help me to know the way to change it. Thanks in ...
Extend the Admin Post/Edit page
I want to create a plugin that will place a few elements on the post edit page. How do I do this? Is there an action that is run after before the post_edit page is loaded?
How to extend the page editor?
I'm really a newbie to WordPress. I can edit the page via admin Page menu. There is a form submitted on that page. How can I write my own functions to handle this form submission? In other words, how could WordPress recognize the route in form ACTION, and forward to my functions? Use a plugin?
Set authentication cookies to be shorter but then extend with every page load
I'm trying to get around the otherwise very insecure way of Wordpress handling authentication cookies. I mean, having the cookie expire in 2 weeks only if I build a membership site is obviously not ok, but at the same time, making it expire in 15 minutes while the user is logged in would be more than annoying. I have searched and tested extensively...

Also ask

We use cookies to deliver the best possible experience on our website. By continuing to use this site, accepting or closing this box, you consent to our use of cookies. To learn more, visit our privacy policy .