0

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'))
  • Please format your code properly. Besides there is a lot of German in there, I incidentally can read it, but generally things should be in English, because it is the common denominator language-wise. Although the code speaks for itself of course. – Nicolai Sep 27 '14 at 12:47
  • Regarding your question, do you mean »sub-header-menu« is the value you want for the theme_location parameter for the wp_nav_menu() call? And, one more addition, you probably should link to the source too. – Nicolai Sep 27 '14 at 12:49
  • Yes »sub-header-menu« is the value I want for the theme_location parameter for the wp_nav_menu() call? – Thomas Schneider Sep 28 '14 at 18:36
  • The Source: it is this Site: mdw.ac.at/filmakademie/de – Thomas Schneider Sep 28 '14 at 18:36
  • Where can i publish the Function again without German? Here in the comment section it is to long, thanks Thomas – Thomas Schneider Sep 28 '14 at 18:51
0

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 = '')
  • Yes, ialocin - that is exactly what i thought should work. But doesn´t. Tried it right now. Somehow the new $args are still written in all menues on page. Including the main menu, and sidebar menues which doesn´t make sense. I wonder how to exclude the other Menues. – Thomas Schneider Sep 30 '14 at 9:23
  • Too bad, what if it is done like in my edit? @ThomasSchneider – Nicolai Sep 30 '14 at 9:34
  • Code in comments isn't a good match, please delete it. So the solution was to check for $args['theme_location'], like I suggested. @ThomasSchneider If you want to add your own answer, which you of course can do, then please add the complete code to it, because I see in the comments code you added code. – Nicolai Sep 30 '14 at 10:51
0

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'))
  • Just to clarify, the solution or main difference between question and answer code is the check for $args['theme_location'] which makes it possible to apply changes to a specific location only. – Nicolai Sep 30 '14 at 11:36

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.