WordPress: Eigenes Menü für bestimmte Seiten

Ich bin ja immer noch dabei, mein „Portfolio“ ein bisschen aufzuarbeiten, und dabei soll WordPress auch als CMS benutzt werden. Jetzt hätte ich gerne auf den Seiten, die ein bestimmtes Projekt beschreiben ein Menü, dass sich auf die Unterseiten dieser Seite beschränkt, und nur einen generelle Link zurück zu Blog hat. Auf dem Blog soll natürlich weiterhin das normale Menü angezeigt werden.

Die Lösung war eine Kombination aus der WP 3.0 Menü Funktion und einem kleinen PHP Hack. Zuerst ein Mal zu der Menü Funktion: Diese Funktion ist mit WordPress 3.0 verfügbar und ermöglicht es, unter Design/Menüs eigene Menüs zu erstellen. (Wenn das Theme das unterstützt) Nur was macht man damit? Zum einem kann das Menü einer Position im Theme zuweisen. Das ist praktisch, wenn man die automatische Menüanordnung nicht mag. Doch mit einem kleinem Eingriff wird das ganz noch mächtiger!

Alles was man machen muss, ist diese Zeilen in die funktions.php des Theme zu kopieren:

<?php
//Filter the arguments for the wp_nav_menu_function to include a custom menu on pages.
function nr_2010_wp_nav_menu_args($args = '')
{
	if(is_page()) //custom menus only on sites
	{
		global $post;
		$page_slug = sanitize_title($post->post_title);

		if(is_nav_menu('page-' . $page_slug)) //if a menu with the name page-{page url form} exists, use it.
		{
			$args['menu'] = 'page-' . $page_slug;
		}
	}
	return $args;
}
add_filter( 'wp_nav_menu_args', 'nr_2010_wp_nav_menu_args' );
?>

Kleine Erklärung: Es wird ein Filter auf die Parameter der wp_nav_menu gesetzt. In diesem Filter kann man die Parameter der Funktion ändern, bevor sie ausgeführt wird. (Alles Teil des genialen Plugin Systems von WordPress) Wenn grade eine Seite (is_page) angefragt wird, wird in der Variable post_slug die URL Form des Titels gespeichert und wenn auch ein Menu existiert (das wie oben beschrieben erstellt wurde), das den Name page-{post_slug} hat, wird dieses statt dem normalem Menü angezeigt.

Viel Text für eine einfache Erklärung: Ich kann einfach ein Menü mit einem passenden Namen erstellen, und es wird anstelle des normalen Menüs angezeigt! Super einfach 😉

Verbesserungsideen: Den Namen des Menüs aus einem Custom Filed des Posts leses…

80 Gedanken zu „WordPress: Eigenes Menü für bestimmte Seiten

  1. Hallo,
    wenn ich den php Code in die function.php kopiere, kann ich nicht mehr in meinen admin Bereich einloggen. Die Ü, Ö und Ä zeigen auch nicht mehr an. Ich habe den php-Code in mein Kind-thmes / function.php kopiert. Über eine Antwort würde ich mir sehr freuen. Gruss Gerd

    1. Das ist seltsam. Ich hab dieses Script hier immer noch im Einsatz und es funktioniert wunderbar. Steht in deiner functions.php Mensch etwas anderes drin? Wenn ja, poste doch mal die komplette Datei, vielleicht hast du den Code an eine ungünstige Stelle kopiert…

      Welches Theme benutzt du denn? Möglicherweise unterstützt das Theme gar keine Customs Menüs?

  2. Hallöchen

    Ich brauche dringend deine Hilfe. Ich habe deine obigen Zeilen wie du beschreibst auf meiner Page eingefügt. Nun geht gar nichts mehr. Die Seite kann nicht mehr angezeigt werden. Kannst du mir bitte helfen meine Seite wiederherzustellen?

    Danke Gruss Seraina

    1. Hallo Seraina,

      Laut der Fehlermeldung gibt es einen Syntaxfehler in der functions.php. (Parse error: syntax error, unexpected ‚*‘) Vermutlich hast du den Code an die falsche Stelle kopiert, und dadurch funktioniert er da nicht. Wenn man Pech hat, kann man sich so wirklich die ganze Seite lahm legen. 🙁

      Da du scheinbar auch keinen Zugriff mehr auf die Admin-Seiten hast, musst du leider per FTP auf den Server zugreifen, und dort die functions.php unter /wp-content/themes/(Name)/ wieder bearbeiten. Die Zugangsdaten für FTP hast du vermutlich bei der Installation von WordPress gebraucht, die hast du bestimmt irgendwo.

      Wenn du deinen Blog gerettet hast, poste doch hier mal die gesamte functions.php Datei, dann finden wir den Fehler bestimmt.

      1. Hallo Niklas

        Ich danke dir vielmals. Jedoch bin ich die absolute Niete und meine Kollegin hat das für mich gemacht. Ich bin echt am verzweifeln. Ich weiss nicht, ob sie die Zugangsdaten noch hat… morgen gehe ich zu einem IT-Spezialisten. Meinst du, kann mir dieser helfen?

        Danke nochmals für die prompte Antwort.

        Gruss
        Seraina

        1. Wenn du die Zugansdaten noch hast, kannst du sie mir gerne per Mail schicken (steht im Impressum) dann kann ich mir das mal ansehen (wenn du das möchtest). Vielleicht hast du die Zugagsdaten per Mail bekommen, und du hast diese Mail noch?

          Ansonsten kann die sicherlich jeder „Spezialist“ helfen, der ein klein wenig Ahnung von WordPress hat, aber vermutlich auch nur mit den Zugangsdaten…

          1. Ich telefoniere morgen mit dem bruder meiner kollegin. der sollte die zugangsdaten haben. sobald ich mehr weiss, melde ich mich gerne bei dir. herzlichen dank für deine hilfestellung.

            schöner abend noch
            seraina

          2. Das sollte kein Problem sein. Es wurde ja nichts gelöscht o.ä. es ist nur etwas verstellt, was man leider jetzt nicht mehr über die Website zurückstellen kann. Wenn man das korrigiert, funktioniert alles so wie immer 🙂

          3. Hallo Niklas

            Es hat geklappt. Wie er das aber bewerkstelligen konnte, weiss ich nicht resp. war da was mit Zeile 19. Da ich den ursprünglichen „Text“ noch hatte, konnte er diesen dann in der Zeile 19 wieder einfügen. War eine Sache von ein paar Minuten.

            Ich danke dir herzlich und wünsche eine gute Zeit.
            Seraina

  3. Hallo,

    habe den Code in die functions.php eingefügt. (Expound_Theme)
    Ziel sollte sein, daß auf der Blog-Seite das erstellte „Blog_menü“ angezeigt wird.
    Hier der abgeänderte Code, der leider auf der Blog-Seite nur das mainmenue anzeigt??

    function nr_2010_wp_nav_menu_args($args = 'blog')
    {
    if ( is_page(blog) ) //custom menus only on sites
    {
    global $post;

    $menu_name = get_post_meta($post->ID, 'Blog_menü', true);

    if( !empty($menu_name) && is_nav_menu($menu_name) )
    {
    $args['menu'] = $Blog_menü;
    }
    }
    return $args;
    }
    add_filter( 'wp_nav_menu_args', 'nr_2010_wp_nav_menu_args' );

    Wo liegt der Fehler

    Schöne Dank für jeden Hinweis

    Werner

    1. Hallo Werner!

      Irgendwie werde ich aus deinen Modifikationen nicht so recht schlau…

      Wenn ich das richtig verstehe, möchtest du auf der Hauptseite (und auf den einzelnen Beiträgen?) ein anderes Menü einblenden?

      Dann würde ich diesen Code benutzen:

      //Filter the arguments for the wp_nav_menu_function to include a custom menu on pages.
      function nr_2010_wp_nav_menu_args($args = '')
      {
      if( is_home() || is_single() ) //custom menu on blog
      {
      $menu_name = "Blog_Menü";
      if( is_nav_menu($menu_name) )
      {
      $args['menu'] = $menu_name;
      }
      }

      if ( is_page() ) //custom menus on pages from meta
      {
      global $post;

      $menu_name = get_post_meta($post->ID, 'menu_name', true);

      if( !empty($menu_name) && is_nav_menu($menu_name) )
      {
      $args['menu'] = $menu_name;
      }
      }
      return $args;
      }
      add_filter( 'wp_nav_menu_args', 'nr_2010_wp_nav_menu_args' );

      (Ungetestet!)

      Dort wird zusätzlich noch abgefragt, ob wir auf der Homepage (is_home()) oder auf einer Post-Seite (is_single()) sind, und dann das Menü „Blog_Menü“ geladen, wenn es denn existiert.

      Vielleicht hilft dir das weiter? Ansonsten noch mal nachfragen 🙂

  4. Hallo Niklas,

    vielen Dank für deine Antwort. Leider funktioniert der code bei mir nicht.
    Ich möchte eine „normale“ homepage mit wordpress erstellen. Darin soll ein Blog eingebaut werden. Ich habe 2 Menüs erstellt:
    1. „mainmenue“ für die homepage
    2. „Blog-Menü“ für den Blog
    Wenn ich auf den „Blog-Link“ des mainmenue klicke, soll – mit anderem Header – ein Blog mit eigenem Blog-Menü erscheinen. Das Blog-Menü soll nicht in der sidebar erscheinen, sondern mit gleichem Aussehen – horizontal – wie das mainmenue.
    Mir ist nicht klar, wo ich in dem code mein „mainmenu“ bzw, das „Blog-Menü“ eintragen muss.

    Vielen Dank für einen weiteren Tip

    Werner

  5. Ah, jetzt verstehe ich, was du vor hast 🙂

    Dann versuche es am besten mal mit diesem, kürzeren Code:


    //Filter the arguments for the wp_nav_menu_function to shwo custom menu on blog pages
    function nr_2012_wp_nav_menu_args($args = '')
    {
    if( is_home() || is_single() ) //custom menu on blog
    {
    $menu_name = "blog_menu";
    if( is_nav_menu($menu_name) )
    {
    $args['menu'] = $menu_name;
    }
    }
    return $args;
    }
    add_filter( 'wp_nav_menu_args', 'nr_2012_wp_nav_menu_args' );

    Der sollte dafür sorgen, dass auf allen Blog-Seiten das Menü mit dem Namen „blog_menu“ angezeigt wird. Den Namen kannst du im Code natürlich ändern.

    Dann erstellt du noch das Menü, das auf allen anderen Seiten angezeigt werden soll, und setzt das unter http://[Deine-Seite]/wp-admin/nav-menus.php?action=locations als Standard für alle Seiten.

    Damit sollte auf allen Seiten das eingestellte Menü erscheinen, und nur auf den Blog-Seiten das spezielle Menü „blog_menu“. Die Custom Post Fields brauchst du dann nicht mehr.

    Ich hoffe so funktioniert es, sonst helfe ich gerne weiter, zumindest bei einer aussagekräftigen Fehlerbeschreibung 😉

  6. Hallo Niklas,

    bist du schnell – toll. Geht leider immer noch nicht.
    Habe im Dashbord unter Menüs mein mainmenue als Hauptmenü und als „Secondary Menu“ das blog_menu erstellt. Ohne Fehlermeldung wird weiter nur das mainmenue angezeigt. Habe dann mit dem Plugin „Custom Menu Wizard“ mein blog_menu ausgewählt. Es erscheint jetzt zwar, aber zusammen mit dem mainmenue.
    Fällt dir noch was ein??
    Schöne Grüße

    Werner

    1. Seltsam… Ich hab es gerade noch mal bei mir ausprobiert, und es hat wunderbar funktioniert.

      Ich habe zwei Menüs angelegt, „blog_menu“ und „main_menu“. Dann habe ich „main_menu“ als primäres Menü eingestellt. Das sieht so aus:

      http://i.imgur.com/dc87J1s.png

      (Es kann sein, das dein Theme da noch mehr Optionen hat, dann auch überall „main_menu“ auswählen. Dann kann dein Theme mehr als ein Menü gleichzeitig anzeigen)

      Dann habe ich den Code von oben an das Ende der functions.php des aktiven(!) Themes kopiert. Danach hatte ich im Blog das „blog_menu“, und auf allen anderen Seiten das „main_menu“.

      Wenn es gar nicht geht, probiere mal das aus:


      function nr_2012_wp_nav_menu_args($args = '')
      {
      $args['menu'] = "blog_menu";
      return $args;
      }
      add_filter( 'wp_nav_menu_args', 'nr_2012_wp_nav_menu_args' );

      Damit wird auf allen Seiten das Menü durch „blog_menu“ ersetzt. Damit kann du sehen, ob der Code überhaupt funktioniert. Und natürlich muss der Name des Menüs genau stimmen, ansonsten wird wieder das „main_menu“ angezeigt.

      Während dieser Tests am besten alle anderen Plugins die was mit den Menüs zu tun haben abschalten. Ich hoffe damit kommst du dem Fehler auf die Spur 🙂

      -Niklas

  7. Hallo Niklas,

    die gute Nachricht: das “blog_menu” wird durch deinen code auf allen Seiten angezeigt.
    Ansonsten hat sich leider nichts geändert. Habe es auch mit dem Twenty Eleven Theme probiert. Welches Theme hast du benutzt?

    Noch einen schönen Abend

    Werner

    1. Das ist ja wirklich seltsam. Ich habe hier das TwentyThirteen Theme zum testen genommen, und hier auf dem Blog läuft TwentyTen.

      Eigentlich sollte das Theme aber egal sein.

      Ich kann mir ehrlich gesagt nicht vorstellen, warum das jetzt nicht funktioniert, gerade weil es ja auch mit dem letzten Code überall angezeigt wird…

      Das einzige was mir noch einfallen würde, wäre mir das mal „vor Ort“ anzusehen, aber dazu müsste ich Zugang zu der entsprechenden WP Installation haben… Ich kann mir aber gut vorstellen, dass du das nicht möchtest… Ansonsten ist mir das echt schleierhaft…

      Schöne Grüße
      Niklas

  8. Hallo Niklas,

    es liegt NICHT an Deinem Code. Ich hatte zur Lösung des Problems – eigenen Header für die Blogseite – unter Einstellungen/Lesen keine Beitragsseite angegeben. Jetzt habe ich meinen Blog als Beitragsseite angegeben und das Menü wird jetzt angezeigt (aber mein Header nicht). Werde mich jetzt mit dem Unique Header Plugin amüsieren in der Hoffnung, dass auch dieses Problem gelöst wird.
    Jedenfalls vielen Dank für die tolle Unterstützung und schöne Grüße aus dem sonnigen Rheinland

    Werner

  9. stimmt. Dank „Unique Headers“ Plugin ist auch mein Headerproblem gelöst und ich kann erst mal meinen PC ausschalten und was an die frische Luft. Nochmals schönen Dank und sonnige Grüße

    Werner

  10. Hallo Niklas,

    leider ist bei den Menüs doch noch ein Problem aufgetaucht. Wenn ich im „Blogbereich“ bin, wechselt das Blog_Menü zum mainmenue, wenn ich die einzelnen Kategorien anklicke. (Bei den Kommentaren und Beiträgen nicht). Unter Dashboard-Menüs gibt es leider keine Möglichkeit, die einzelnen Kategorien mit dem dem Blog_menü zu verbinden.
    Wäre schön, wenn dir hierzu ein Lösung einfallen würde.

    Schöne Grüße

    Werner

    1. Das lässt sich einfach beheben: Einfach die Zeile
      if( is_home() || is_single() )
      durch
      if( is_home() || is_single() || is_category())
      austauschen. Dort kannst du auch noch mehr „Contitional Tags“ einbauen, wenn dir danach ist 😉

  11. Hallo Niklas,

    danke für die tolle Anleitung!
    Aber ich bin leider ein kompletter Grünschnabel und verstehe nicht wo ich in den Code den MENÜNAMEN und die SEITEN-ID eingeben muss…

    Einfaches Beispiel:
    Das alternative Menü, das ich auf einer bestimmten Seite haben will, nennen wir „menü2“. Dieses lege ich nun an (unter Design > Menüs). OK! Nun will ich „menü2″auf der Seite mit der Page ID 12 haben. Wo schreibe ich „menü2“ rein und wo die Page ID?

    Es wäre ein Traum, wenn du mir helfen kannst!

    Vielen Dank schon mal!!!
    Tina

    1. Hallo Tina!

      Bei dem Code hier wird der Name des Menüs aus dem Namen der Seite abgeleitet. Wenn ich also zum Beispiel für diesen Artikel ein eigenes Menü haben will, muss es den Namen „menu-wordpress-eigenes-menu-fur-bestimmte-seiten“ haben.

      Das ist natürlich ein wenig umständlich, darum gibt es hier eine verbesserte Version: http://bueltge.de/benutzerdefinierte-felder-zum-steuern-des-wordpress-nav-menu/

      Dort wir der Name des Menüs aus einem „benutzerdefinierten Feld“ gelesen, genauer gesagt dem Feld mit dem Namen „menu_name“. Du musst jetzt also die Seite Nummer 12 bearbeiten, oben auf „Optionen“ klicken, und dort den Editor für benutzerdefinierte Felder aktivieren, und dann ein Feld mit dem Namen „menu_name“ und dem Wert „menü2“ anlegen. Dann sollte das Menü angelegt werden.

      Ich kann dazu gerne auch noch mal ein Bild posten, falls das helfen sollte 😉

      Im Code muss jedenfalls in beiden Versionen nichts geändert werden.

      Schöne Grüße
      Niklas

      1. Hallo Niklas,

        erstmal vielen lieben Dank für das super schnelle Feedback, Wahnsinn!!

        Nun habe ich es gemacht wie von dir (in der neuen Version) beschrieben und bekommen diese Fehlermeldung (siehe unten), der vermutlich durch das Theme hervorgerufen wird 🙁
        Hast du zufällig eine Idee?

        Viele Grüße!
        Tina

        //Filter the arguments for the wp_nav_menu_function to
        Warning: Cannot modify header information – headers already sent by (output started at /var/www/web991/html/wp-content/themes/maxima-v1-04/functions.php:163) in /var/www/web991/html/wp-admin/post.php on line 233

        Warning: Cannot modify header information – headers already sent by (output started at /var/www/web991/html/wp-content/themes/maxima-v1-04/functions.php:163) in /var/www/web991/html/wp-includes/pluggable.php on line 896

        1. Hi,

          Das sieht irgend wie so aus, als ob du den Code nicht richtig in die functions.php eingebunden hast. Kannst du vielleicht mal die ganze Datei posten?

          Ich vermute, der Code steht nicht zwischen den Tags…

          1. Moin Moin Niklas,

            ah ok, gelöst! Dachte der Code muss ans Ende.. Nun habe ich ihn an den Anfang gestellt und jetzt passt es 😉 Klasse! Vielen Dank!!!

            Sag mal, hast du vielleicht auch eine Idee, wie das Logo im Header auf bestimmten Seiten ausgetaucht werden kann (eigentlich ähnliche Thematik)?

            Viele Grüße!
            Tina

          2. Hi Tina,

            Ja dass sollte sich ganz ähnlich machen lassen. Dafür scheint es aber auch schon ein paar Plugin zu geben, ich habe gerade diese gefunden: https://wordpress.org/plugins/custom-header-extended/

            Mit ein wenig Googlen schient man da eine Menge zu zu finden. Im Grunde könnte man sicher auch das Plugin oben anpassen, wenn du nichts passendes findest 😉

            Niklas

  12. Hallo Niklas,

    vielen Dank für Deinen vielversprechenden Ansatz zur Erstellung eigener Menüs für bestimmte Seiten.

    Auf bueltge.de hast Du Dich dem Thema auch angenommen und ja auch einige Anwenderfragen beantwortet. Einer von diesen wollte erreichen, dass das Hauptmenü gleich bleibt, aber ein zweites Untermenü sich mit jeder Seite verändert. Du hattest folgendes vorgeschlagen: „Das lässt sich relativ einfach einbauen: Hinter das is_page() kommt noch ein && $args[‚theme_location‘] == ‚xxxx‘. Das ganze muss noch in die if Klammer! Statt dem xxx musst du natürlich den Namen der Location angeben, für dass du den dynamischen Wechsel möchtest.“

    Jetzt möchte ich darauf nochmals zurückkommen: Auch ich bräuchte, dass ein Hauptmenü (obern quer) fest stehen bleibt, sich jeder Seite aber ein anderes Untermenü (seitlich) zuordnen lässt. Es gibt beide Menüs, eines ist im „register_nav_menus“ eingetragen, das andere habe ich über Widget „Individuelles Menü“ (Position Sidebar) eingebunden. Wie kann ich jetzt dieses individuelle Untermenü nach Deiner Methode adressieren, ohne dass davon das Hauptmenü betroffen wird?

    Hast Du denn eine Idee?

    Danke & schöne Grüße,
    Thomas

    1. Hi Thomas,

      das ist tatsächlich gar nicht so einfach, denn leider gibt das Widget keine Kennung an wp_nav_menu, an der man den Zugriff identifizieren kann… Aber wenn du Glück hast, gibt das Theme die ‚theme_location‘ an, dann kannst du das Widget daran identifizieren, dass die ‚theme_location‘ eben nicht gesetzt ist. Um da genaueres sagen zu können, müsste ich wissen, welches Theme du benutzt, oder du musst zumindest mal den Aufruf von wp_nav_menu des Themes posten 😉

      So ganz einfach ist das auf jeden Fall nicht… Es bleiben natürlich immer noch Hacks, wie mitzählen, wie oft der Filter aufgerufen wird… Aber das geht natürlich ganz schnell schief, wenn man mal was am Theme ändert 😛

      Schöne Grüße
      Niklas

      1. Hallo Niklas,

        vielen Dank für Deine Antwort.

        Mittlerweile (und nach etlichen vergeblichen anderen Versuchen) bin ich auf ein Plugin names „Per Page Sidebars“ gestoßen (http://wordpress.org/plugins/per-page-sidebars/) mit dem ich das Seitenmenü im Widgetbereich sowie das Bottommenü im Footer individuell zuteilen kann, ohne dass davon das Hauptmenü beeinträchtigt wird. Wie sauber das Plugin arbeitet, kann ich nicht beurteilen – auf den ersten Blick jedoch scheint alles gut zu funktionieren.

        Schöne Grüße,
        Thomas

  13. hallo
    danke für interessanten ausführungen – aber ich werde nicht schlau – ich will (wp4) folgendes machen
    1. Eingangsseite mit silder und hinweis auf drei unterwebs
    2. pro unterweb eine eigene hauptnavi
    3. ich verwende twentytwelve-child mit hauptmenue( das soll in jedem bereich anders sein) und einem top menue (da sollen meine drei bereiche hin)
    bisher hab ich nur eine lösung mit installation von drei wp’s – alle in einem eigenen ordner( quasi selbständig…)
    kann ich das mit deinem code einfacher lösen? und wo genau einfügen?
    danke bestens
    pke

    1. Hi,

      Also vermutlich könnte man da aus dem Code oben irgendetwas basteln, aber so wirklich super würde das nicht werden. Du hast ja im Grunde drei unabhängige Website, die zu zusammenfassen willst.

      Ich würde mir mal das Multisite (aka MU) Feature von WordPress ansehen: http://codex.wordpress.org/Create_A_Network
      Damit kannst du im Endeffekt mehrere getrennte Installation von WordPress haben, aber alle laufen mit dem gleichen Kern (also musst du z.B. Updates nur ein Mal machen). Ist leider nicht so einfach aufzusetzen, da es sich mehr an Admins richtet. Mit ein bisschen technischem Background sollte das aber machbar sein. Ich würde mal vermuten, dass das die beste Lösung für dein Problem ist…

      -Niklas

  14. Hallo, super interessant.
    Habe folgendes Problem:
    Habe den normalen Main Menu und auf Seite A soll zusätzlich Menu A erscheinen und auf Seite B Menu B usw. Main Menu bleibt aber auf allen Seiten erhalten. Mit Ihrem Code kann ich aber nur das Main Menu auf A oder B oder C verändern.
    Wie kann ich den Code für ein zweites Menu nutzen? Soll ich für ein zweites Menu auch etwas in header.php verändern?

    1. Hallo, habe jetzt bei functions.php
      ein primary2 Menu registriert
      register_nav_menus( array(
      ‚primary2‘ => ‚Primary Menu 2‘,));

      und dieses bei header.php mit
      wp_nav_menu( array( ‚theme_location‘ => ‚primary2‘, ‚container_class‘ => ‚menu-footer‘) ); eingefügt.

      Nun geht es nur darum, dass Ihr code ganau auf dieses „primary2“ auswirkt und nicht auf das primary Menu.

      1. Hi,

        das ist ganz einfach: Einfach zwischen Zeile 4 und 5 noch das hier einfügen:

        if($args['theme_location'] != "primary2") return $args;

        Damit wird der Code nur aktiv, wenn gerade das Menü „primary2“ gefiltert wird.

  15. Hallo 🙂

    Ich habe auch eine Frage denn ich komme gerade ins stolpern.
    ich habe eine Seite mit einem Mainmenu Namens“Normales Menu“
    jetzt übersetze ich die Seite gerade auf english also brauch ich ein zweites Main Menu für die Englische Seite was ich auch angelegt habe mit dem Namen „englishmenu“

    Wie würde der Code für mich dann aussehen, dass auf dem englischen Teil der Seite das englische Menu angezeigt wird ?

    Mein Versuch:
    function nr_2012_wp_nav_menu_args($args = “)
    {
    if( is_home() || is_single() )
    {
    $menu_name = „englishmenu“;
    if( is_nav_menu($menu_name) )
    {
    $args[‚englishmenu‘] = $menu_name;
    }
    }
    return $args;
    }
    add_filter( ‚wp_nav_menu_args‘, ’nr_2012_wp_nav_menu_args‘ );

    1. Hi Marius,

      also so funktioniert das auf jeden Fall nicht. Wie kann man denn feststellen, ob man im englischen Teil der Seite ist? Dafür muss dann eine Bedingung in das erste if, und in den Body des zweiten ifs muss dann etwas in Richtung von


      $args['menu'] = $menu_name;


      $args['menu']
      gibt an, welches Menü benutzt werden soll. Das muss eben geändert werden, wenn man sich auf der englischen Seite befindet. Ich glaube, inzwischen wird für mehrsprachige Blogs übringens WP-MU empfohlen, da hat man dann das Problem nicht, weil die zweite Sprache ein (fast) komplett unabhängiger Blog ist.

      Schöne Grüße
      Niklas

  16. Hallo,

    erstmal brilliant muss ich sagen habe den code ausprobiert und es funktioniert tadellos.

    nun habe ich alerdings ein aderes problem ich habe das plugin coutemer area instlaiert da ich für die webseite einen „abgetrennten“ kundnebereich brauche.

    genau hier will ich deine Lösung einsetzen.
    bei der instalation des themes wird automatisch ein zweites dropdown menu angelegt unter Menüs –> Positionen Verwalten

    ich kann also hier ein menü + position für das normale theme und eben den „Kundnebereich“ anlegen leider funktioniert das nicht da das zweite menü im „textbereich“ angezeigt wir.

    Nun habe ich auf der Seite auf der der kundnebereich angezeigt wird das normale menü mit deiner lösung ersetzt und das passt auch.

    wenn ich nun aber unter „Positionen Verwalten“ dem Kundenbereich kein menü zuweise erhalte ich folgene meldung:
    Warning: Attempt to assign property of non-object in /../themeple_coustum_menu.php on line 373

    hast du villeich irgend eine idee was ich da machen kann?

    vielen dank schonmal!

    1. Hi,

      also so ganz verstehe ich nicht, was du machen möchtest… Möchtest du, dass mein Code das zweite Menü auf der Kundenseite in Ruhe lässt? Oder willst du einfach nur auf der Kundenseite ein anderes Menü anzeigen (dafür scheint doch die zweite Menüposition im Backend zu sein…)?

      Irgendwie klingt das so, als würde das Plugin für den Kundenbereich nicht richtig funktionieren und du würdest versuchen das mit meinem Plugin zu reparieren 😉 In dem Fall würde ich mich an den Entwickler des Kundenbereichs-Plugin wenden, der kann dir da sicher besser helfen… Oder habe ich dein Problem noch nicht ganz verstanden?

  17. Hi Niklas,

    ich habe mir hier alles einmal durchgelesen und mein Problem konnte ich leider noch nicht lösen. Ich hoffe, du kannst mir weiterhelfen.

    Also, meine Ziel ist es eine statische Seite als Hauptseite festzulegen. Diese Hauptseite hat ein Hauptmenü mit drei verschiedenen Links. Z.B. so ( Link1 – Link2 – Link3 )
    Wenn man jetzt auf Link1 klickt, soll eine weitere statische Seite erscheinen, die optisch genauso aussieht wie die erste, nur das Menü soll dann ein Komplett anderes werden. Ich könnte mir auch Multisites vorstellen, würde mich aber freuen, wenn ich das ganze mit weniger Aufwand hinbekommen würde ;-).

    Geht das mit deinem Code?

    Vielen Dank und viele Grüße!
    Christopher

    1. Hi,

      ja, prinzipiell geht das. Du müsstest drei verschiedene Seiten erstellen, die alle den gleichen Inhalt haben, und dann jeweils verschiedene Menüs zuweisen. Ich denke aber, das ist der falsche Weg. Wäre nicht vielleicht ein Dropdown-Menü eine bessere Idee, bei dem das „neue“ Menü ausklappt, wenn man auf einen Menüpunkt klickt? Wenn du wirklich das sich austauschende Menü haben willst, würde ich das mit JavaScript auf einer Seite machen, die Variante mit drei fast identischen Seiten klingt für mich sehr unsauber…

      Schöne Grüße
      Niklas

  18. Hi Niklas,

    ich habe dein script in einer leicht abgewandelten Form verwendet.
    Bei mir werden aber beide verwendeten Menüs überschrieben. Wie kann ich das verhindern.
    hier mein Code:

    //Filter the arguments for the wp_nav_menu_function to include a custom menu on pages.
    function change_wp_nav_menu_args($args = “)
    {

    global $post; // if outside the loop
    $page_object = get_queried_object();
    $page_id = get_queried_object_id(); // Get current page id

    $args1 = array(
    ’sort_order‘ => ‚ASC‘,
    ’sort_column‘ => ‚post_title‘,
    ‚hierarchical‘ => 1,
    ‚exclude‘ => “,
    ‚include‘ => $page_id,
    ‚meta_key‘ => “,
    ‚meta_value‘ => “,
    ‚authors‘ => “,
    ‚child_of‘ => 0,
    ‚parent‘ => -1,
    ‚exclude_tree‘ => “,
    ’number‘ => “,
    ‚offset‘ => 0,
    ‚post_type‘ => ‚page‘,
    ‚post_status‘ => ‚publish‘
    );
    $pages = get_pages($args1);

    $parentID = $pages[0]->post_parent; // Get current page parent id
    $pageID = get_the_id();
    if ($parentID == 2789 || $pageID == 2789) //custom menus only on sites
    {
    if(is_nav_menu(‚Menue-akademie‘)) //if a menu with the name page-{page url form} exists, use it.
    {
    $args[‚menu‘] = ‚Menue-speaker-main‘;
    }
    }
    return $args;
    }
    add_filter( ‚wp_nav_menu_args‘, ‚change_wp_nav_menu_args‘ );

    Danke

    Gruß, Olli

  19. Hi Niklas,
    ist primary2 dann der Name des Menüs, dass ich nicht überschreiben möchte?
    if($args[‚theme_location‘] != „primary2“) return $args;

    1. Ja genau. Wie der Name genau lautet musst du leider aus dem Code (oder der Doku) des Themes raus suchen. Wenn du mir sagst, um welches Themes es geht, kann ich aber auch gerne für dich nachsehen.

  20. Hallo Niklas!
    Ich habe bei meiner Website ebenfalls ein Problem mit meiner Navigationsleiste.
    Ich habe eine Website erstellt, bei der alle wichtigen Infos auf einer Seite sind (sprich One-Page und die einzelnen Menüpunkte sind mit den verschiedenen Abschnitten verankert). Habe aber noch ein paar „neben Seiten“ (z.B. Impressum) diese Seiten sind bei mir im Footer aufgelistet. Wenn ich mich auf der Impressum-Seite befinde, habe ich dann natürlich die Nav-Leiste von der Startseite, möchte aber ein anderes Menü dort aufgelistet haben.
    Dafür habe ich in meiner child functions.php diesen Code eingefügt:

    Es funktioniert auch, nur werden dann auch meine Menüpunkte im footer geändert (Menü als Widget). Wie kann ich das verhindern???

    1. Hier nochmal der Code, wurde anscheinend nicht mitgeschickt.

      function change_wp_nav_menu_args($args = “)
      {
      $pageID = get_the_id();
      if($pageID == ‚196‘) //custom menu for site with id 196
      {
      $args[‚menu‘] = ’second-menu‘;
      }
      return $args;
      }
      add_filter( ‚wp_nav_menu_args‘, ‚change_wp_nav_menu_args‘ );

      1. Hi Magda,

        du musst in irgendeiner Weise erkennen, ob gerade das Menü im Foster gefiltert wird. Vermutlich kann man das über die „Theme-Location“ erkennen, ich weiß aber nicht genau, wie das Menü im Footer umgesetzt ist. Ich würde als erste Zeile nach der geschweiften Klammer sowas einfügen:

        if ($args[‚theme_location‘ != ‚primary‘]) return $args;

        Ob der Name von dem Menü oben wirklich „primary“ ist, hängt aber von deinem Theme ab.

        -Niklas

  21. Hallo,

    für ein Magazin bisher Drupal jetzt WordPress brauche ich mehrere Navigationen, z.B. Schule, Kindergarten, News.

    Ich habe das php in der functions.php ausprobiert, erhalte aber immer wieder Fehlermeldungen ;-(

    Könnte mir jemand dabei behilflich sein, das wäre sehr nett!!

    lg
    Uli

  22. Hallo erst einmal, vielen Dank für diesen tollen Beitrag.

    Leider habe auch ich das Problem, dass mein Theme (betheme) zwei Menüs besitzt und beide überschrieben werden, ich aber natürlich nur möchte, dass eines der beiden (in meinem Fall das Mainmenü im Header) überschrieben wird. Ich habe deine angepasste Version aus dem Blog von Frank Bültge eingebaut. Wo muss ich dort die Theme Location einbauen?

    Ich danke schon im Voraus für die Hilfe und die tolle Arbeit hier.

    Liebe Grüße,
    Steven

      1. Vielen Dank für die Antwort, ich habe leider noch nicht ganz rausfinden können, wie ich die Theme Location finde. Würde mich über einen Denkanstoß freuen.

        Vielen Dank. Liebe Grüße.

        1. Irgendwo im Theme muss das Menü registriert werden, durch einen Aufruf von register_nav_menu('name');. Dabei ist name die gesuchte Theme-Location. Leider ist das Theme was du benutzt nicht Open-Source, daher musst du selber im Code suchen (oder beim Autor nachfragen).

  23. Ich habe das jetzt so gefunden:
    /* —————————————————————————
    * Registers a menu location to use with navigation menus.
    * ————————————————————————— */
    register_nav_menu( ‚main-menu‘, __( ‚Main Menu | depth 5 (Header Overlay 1)‘, ‚mfn-opts‘ ) );
    register_nav_menu( ’secondary-menu‘, __( ‚Secondary Menu | depth 2 (Header Split 5)‘, ‚mfn-opts‘ ) );
    register_nav_menu( ‚lang-menu‘, __( ‚Languages Menu | depth 1‘, ‚mfn-opts‘ ) );
    register_nav_menu( ’social-menu‘, __( ‚Social Menu Top | depth 1‘, ‚mfn-opts‘ ) );
    register_nav_menu( ’social-menu-bottom‘, __( ‚Social Menu Bottom | depth 1‘, ‚mfn-opts‘ ) );

    In die functions.php des child-themes hab ich jetzt das ganze so eingebunden:

    //Filter the arguments for the wp_nav_menu_function to include a custom menu on pages.
    function nr_2010_wp_nav_menu_args($args = “)
    {
    if ($args[‚theme_location‘ != ‚main-menu‘]) return $args;
    if ( is_page() ) //custom menus only on sites
    {
    global $post;

    $menu_name = get_post_meta($post->ID, ‚menu_name‘, true);

    if( !empty($menu_name) && is_nav_menu($menu_name) )
    {
    $args[‚menu‘] = $menu_name;
    }
    }
    return $args;
    }
    add_filter( ‚wp_nav_menu_args‘, ’nr_2010_wp_nav_menu_args‘ );

    Leider geht es dennoch nicht, ich muss dazu sagen, das zweite Menü im Footer habe ich als Widget eingebunden, liegt das vllt daran?

    1. Was „geht noch nicht“? Das ist etwas vage 😉 Werden immer noch beide Menüs ausgetauscht? Aus welchem Plugin stammt das Widget? Jetpack? Könnte sein, dass das dann nicht funktioniert, das müsste ich mir mal ansehen.

      1. Ich habe gerade gesehen, dass „Menü als Widget“ ja gar nicht aus Jetpack stammt, sondern Teil des Cores ist. Das Menü dort sollte aber auch durch den Filter oben laufen. Allerdings ist dort die theme_location immer auf einen leeren Wert gesetzt. Da dein Code oben aber nur bei main-menu aktiv wird, sollte er das Menü im Widget nicht kaputt machen…

  24. Hallo Niklas,

    ich experimentiere nun schon seit Tagen mit dem Code herum, aber bekomme einfach nicht das hin, was ich gern möchte.
    Ich habe mir eine secondary Menüposition in der functions.php und header.php angelegt.
    Ich habe mehrere Seiten, die ich im primary Menü als Menüpunkte anzeige, z.b. Seite1, Seite2,….
    Nun möchte ich, wenn man auf Seite1 klickt, dass ein weiteres komplexes Menü nur für „Seite1“ erscheint.
    Gerne im secondary Menü-Bereich, weil da kann ich ja wiederrum mit dem Style herumbasteln.

    Ich hab auch den Code von dir auf https://bueltge.de/benutzerdefinierte-felder-zum-steuern-des-wordpress-nav-menu/ ausprobiert, aber da mache ich wohl was falsch.

    Der obige Code hier, hat sehr gut funktioniert, aber ich möchte nicht, dass das primary-menü ersetzt wird. Ich habe dann vergebens versucht als target irgendwie das secondary-menü anzugeben. Hab auch mit Varianten aus den Kommentaren herumprobiert. Habs nicht hinbekommen. 🙁

    Vielleicht hast du einen Tipp, wie ich das hinkriege.

    Liebe Grüße
    JTea

    1. Hi,

      Also ohne weitere Modifikation sollte der Code eigentlich immer alle Menüs auf der Seite ersetzen. Ist das bei dir der Fall? Dann hilft die Zeile if ($args[‚theme_location‘ != ‚main-menu‘]) return $args; um nur das angegebene Menü zu ersetzen, und alle anderen in Ruhe zu lassen (wie in dem Kommentar von Steven W. etwas weiter oben).

      -Niklas

      1. Lieber Niklas,

        vielen Dank für deine Antwort. Ich habe die letzten Tage nochmal herumprobiert, aber bekomme es einfach nicht hin.

        Ich habe mich entschieden, dass untenstehende Variante annähernd hinkommt (??).

        function nr_2010_wp_nav_menu_args($args = “)
        {
        if ($args[‚theme_location‘ != ‚primary‘])
        {
        if ( is_page() ) //custom menus only on sites
        {
        global $post;

        $menu_name = get_post_meta($post->ID, ‚menu_name‘, true);

        if( !empty($menu_name) && is_nav_menu($menu_name) )
        {
        $args[‚menu‘] = $menu_name;
        }
        }
        return $args;

        $args [‚theme_location‘] = ‚secondary‘;
        }
        return $args;
        }
        add_filter( ‚wp_nav_menu_args‘, ’nr_2010_wp_nav_menu_args‘ );

        Ich möchte sagen:
        Wenn es ein Menü gibt, dass nicht als theme_location ‚primary‘ hat und
        Wenn es eine Seite gibt, die in einem Menü vorhanden ist (im Menü, dass als theme-location ‚primary hat) und enn es ein Menü gibt, das so heißt wie die Seite im Menü
        Dann weise diesem Menü als theme_location ’secondary‘ zu.

        Worauf ich hinaus will:
        .. ist, wenn ich im primary Menü auf Menüpunkt-1 klicke, dass ich im secondary Menü nur das Menü-1 bekomme. Wenn ich im primary Menü, Menüpunkt-2 anklicke, bekomme ich im secondary Menü nur das Menü-2.

        (Ich habe das mal ganz anders über Seitentemplates oder auch über die header.php versucht. Ergebnis header.php -> es wird Menü-1 und Menü-2 in secondary angezeigt, Ergebnis Seitentemplate -> z.b. Menü-1 verschwindet wieder, wenn ich einen Menüpunkt in Menü-1 aufrufe… dann ist es ja nicht mehr die Seite.)

        Vielleicht hättest du nochmal einen Tipp für mich. 🙂

        Viele Grüße
        JTea

        1. Hi,

          Also der Code oben ist auf jeden Fall nicht ganz korrekt, alleine die Menge der Klammern passt schon nicht so ganz… Das Ende sieht irgendwie so aus, als gehört es da nicht hin.

          Es ist nicht möglich, den Wert von ‚theme_location‘ in dem Filter zu ändern (bzw. es hat keine Effekt). Der Filter wird immer dann ausgeführt, wenn gerade ein Menü angezeigt wird. Um welches Menü es sich handelt, kann man aus ‚theme_location‘ lesen, und man kann in dem Filter auch beeinflussen, wie bzw. welches Menü anzeigt wird. Durch das Ändern von ‚theme_location‘ kann man das Menü aber nicht „verschieben“.

          Eigentlich sollte der Code funktionieren. Es wird das „Primary“-Menü nicht angefasst, und alle anderen Menüs durch das Menü aus den Meta-Informationen des aktuellen Posts ersetzt. Hast du für die Seiten überhaupt ein Meta-Feld mit dem Namen ‚menu_name‘ angelegt?

          Schöne Grüße
          Niklas

  25. Supercool. Supersimpel. Funktioniert einwandfrei auch mit der aktuellen WP-Version und Elementor.
    1000 Dank.
    gibt es mittlerweile eine Alternative Möglichkeit bzw. ein entsprechendes Plugin – sonst müsste man den Schnipsel doch nach einem Theme-update erneut einpflegen, oder?

    Soweit ists aber erstmal Topp!

  26. Hallo,
    ich nutze Worpress 6.1.1 und will meine Webseiten in zwei Sprachen haben, DE und EN. Jede Sprache hat ihre eigenen Seiten und deshalb auch ein eigenes Menü.
    Deshalb wollte ich deinen Code verwenden. Jedoch komme ich damit nicht zurecht. Zumindest funktioniert es bei mir nicht.
    Ich deinen Code in ein eigenes Plugin verschoben (wie hier beschrieben https://www.webtimiser.de/custom-functions-dein-wp-plugin-snippets/ )
    Meine Frage:
    Welcher Seite-Name ist gemeint? Ist es der Titel? Oder der Permalink?

    Danke im Voraus.

    1. Mein Code nutzt die Ausgabe von „sanitize_title($post->post_title)“, also der Titel, aber in Kleinbuchstaben und mit Leerzeichen durch Minus ersetzt. Das ist meistens auch der Permalink.

      Man könnte statt dessen auch „$post->ID“ benutzen, also die Nummer der Seite, das könnte etwas einfacher sein.

      Hilft dir das weiter?

        1. Das könnte sein. Ich bin mir nicht sicher was du „sanizize_title“ alles verändert wird, vielleicht wird der Unterstrich zu einem Minus oder komplett entfernt.

  27. Hey Niklas,
    das funktioniert super, danke Dir.

    Nun versuche ich, für alle Seiten, bei denen ich über die Custom-Fields ein neues Feld:
    menu_type = ‚EN_‘
    hinterlege, jegliche Menüs gezogen werden, die wie das originale Menü heißen, nur mit einem EN_ vorgestellt!

    Also aus BURGER wird EN_BURGER, aus HEADER wird EN_HEADER !

    Sodass ich quasi folgender Code entsteht,
    wobei ich keine Ahnung habe, wie ich nun alle Menünamen hole und diese dann wieder neu belege!

    Hast Du eine Idee wie man das macht?

    Folgend mein Code-Snippet wie ich mir das vorgestellt habe:

    // holen des Menütyps aus Custom-Fields
    $menu_type = get_post_meta($post->ID, ‚menu_type‘, true);

    // Check, ob ein anderer Typ hinterlegt ist
    if !empty($menu_type) {

    // Aufbau des Arrays mit allen Seiten-Namen
    // gibt es sowas in der Art?
    $menus = get_all_menus_on_site();

    // Loop über jedes gefundene Menü
    foreach($menus AS $menu_name) {

    // Check, ob das Menü existiert
    if is_nav_menu( $menu_type . $menu_name) {
    // neu belegen?
    $args[‚???‘] = $menu_type . $menu_name;
    }
    }
    }

    oder macht es mehr Sinn, die einzelnen Menütypen, die es gibt einfach Stumpf in den Fällen zu ersetzen? (gibt ja nun nicht so viele)

    Dann müsste ich aber immer noch diese auslesen können,
    also sowas wie:

    $menu_name_primary = get_menu_name_from_theme_position(‚primary‘);
    $menu_name_secondary = get_menu_name_from_theme_position(’secondary‘);
    $menu_name_canvas = get_menu_name_from_theme_position(‚off-canvas‘);
    $menu_name_footer = get_menu_name_from_theme_position(‚footer‘);

    und ich diese Namen mit dem menu_type = ‚EN_‘ konkateniere:

    $args[‚primary menu‘] = $menu_type . $menu_name_primary;
    usw. wenn es sowas gibt?

    Ich würde mich ultra freuen, wenn Du mir hier auf die Sprünge helfen könntest!

    Vielen lieben Dank und noch einen guten Start in die Woche

    Sven

    1. Hallo Sven,

      ich glaube du hast einen Denkfehler: Der wp_nav_menu_args Filter wird für jedes Menü einzeln aufgerufen, nicht nur einmal beim Start oder so. In dem Filter wird immer nur ein Menü bearbeitet.

      Theoretisch müsste es etwa so funktionieren:

      function filter_wp_nav_menu_args($args = '')
      {
      global $post;
      $menu_type = get_post_meta($post->ID, 'menu_type', true);
      if(!empty($menu_type))
      {
      $new_name = $menu_type . $args['menu'];

      if(is_nav_menu($new_name)
      {
      $args['menu'] = $new_name;
      }
      }
      return $args;
      }
      add_filter( 'wp_nav_menu_args', 'filter_wp_nav_menu_args' );

      In $args[‚menu‘] ist der Name des Menüs das eigentlich gerade angezeigt wird. Falls es ein anderes Menü mit dem passenden Präfix gibt, wird der Wert überschrieben. Oder habe ich falsch verstanden was du eigentlich vorhast?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert