{"id":166584,"date":"2017-08-11T13:00:57","date_gmt":"2017-08-11T13:00:57","guid":{"rendered":"https:\/\/premium.wpmudev.org\/blog\/?p=166584"},"modified":"2022-04-01T00:33:19","modified_gmt":"2022-04-01T00:33:19","slug":"automatically-update-wordpress-navigation-menus","status":"publish","type":"post","link":"https:\/\/wpmudev.com\/blog\/automatically-update-wordpress-navigation-menus\/","title":{"rendered":"How to Automatically Update Menus When Adding Pages to WordPress"},"content":{"rendered":"<p>When the navigation menu system was released with WordPress 3.0, it was one of the factors that turned WordPress from a blogging platform into a CMS.<\/p>\n<p>It meant that you could add whatever content you wanted to your site&#8217;s navigation menus, including custom links. The drag and drop interface meant that anyone could create their own custom menu without any coding skills.<\/p>\n<p>But sometimes you don&#8217;t want to rely on this. If you&#8217;re developing a site for a client who&#8217;s going to be adding pages to their site but is unlikely to update the navigation menu(s) when they do so, or don&#8217;t have the skills to, then an automated navigation menu can be useful.<\/p>\n<p>If all you want done is to have top-level pages automatically be added to a menu, WordPress makes it easy with the <em>Menu Settings &gt; Auto add pages<\/em> feature.<\/p>\n<p>Just tick the Auto add pages checkbox and click Save. New top-level pages will then be automatically added to the menu you have selected.<\/p>\n<figure id=\"attachment_207925\" class=\"wp-caption aligncenter\" data-caption=\"true\"><a rel=\"lightbox[166584]\" class=\"blog-thumbnail\" href=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2017\/08\/menu-auto-add-pages.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-207925\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2017\/08\/menu-auto-add-pages.png\" alt=\"Auto add pages to WordPress menu.\" width=\"600\" height=\"472\" \/><\/a><figcaption class=\"wp-caption-text\">Auto adding new top-level pages in WordPress menus is easy.<\/figcaption><\/figure>\n<p>If, however, you also want submenu pages to be automatically added to menus, then a little fiddling with code is required.<\/p>\n<p>In this post, I&#8217;m going to show you how to create an automated navigation menu that displays all of the pages in your site, with child pages shown as second level entries in the navigation menu.<\/p>\n<p>You can then add this code to your page header in your theme, or to your sidebar or footer if you want, and it will give your users links that automatically update when new content is added to your site.<\/p>\n<p>Continue reading, or jump ahead using these links:<\/p>\n<ul>\n<li><a href=\"#what-you-need\">What You\u2019ll Need to Automate WordPress Navigation Menus<\/a><\/li>\n<li><a href=\"#setting-up-the-code\">Setting up the Code<\/a><\/li>\n<li><a href=\"#function\">Creating a Function to List All Pages Hierarchically<\/a><\/li>\n<li><a href=\"#adding-function-to-theme\">Adding the Function to the Theme<\/a><\/li>\n<li><a href=\"#improving-the-function\">Improving the Function<\/a><\/li>\n<\/ul>\n<h2 id=\"what-you-need\">What You&#8217;ll Need to Automate WordPress Navigation Menus<\/h2>\n<p>To follow along with this post, you&#8217;ll need:<\/p>\n<ul>\n<li>A development or testing installation of WordPress, with some pages and subpages added, and<\/li>\n<li>A code editor.<\/li>\n<\/ul>\n<p>All of the code is on <a href=\"https:\/\/github.com\/rachelmccollin\/wpmudev-automated-menus\" target=\"_blank\">GitHub<\/a> so if you get stuck, you can interrogate that to see what you should be doing.<\/p>\n<h2 id=\"setting-up-the-code\">Setting up the Code<\/h2>\n<p>I&#8217;m going to add this code to a plugin so that I&#8217;ve still got it if I should change my theme in future. That way, I can then code the function from my plugin into my theme to add the navigation menu or section menu in the right place. If your theme has hooks, you could use one or more of those to add your code.<\/p>\n<p>If you&#8217;re working with a third party theme that doesn&#8217;t have hooks, you&#8217;ll have to add code to the theme. Don&#8217;t code this directly into the theme: instead, <a href=\"https:\/\/wpmudev.com\/blog\/how-to-create-wordpress-child-theme\/\" target=\"_blank\">create a child theme<\/a> and add your code to that. Just make a duplicate of the theme template file from the parent theme that you want to edit, add that to your child theme and edit it.<\/p>\n<p>The first step is to create the plugin. I&#8217;m creating a folder for mine in my <em>wp-content\/plugins<\/em> folder. Creating a folder means I can add more files to the plugin in future if I need to, such as a stylesheet or include files.<\/p>\n<p>First you need to add the opening code to your plugin, in comments, to tell WordPress what this is:<\/p>\n<div class=\"gist\" data-gist=\"5d799dbd9f723a77fc6ea125b1c35318\" data-gist-file=\"plugin_opener.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/5d799dbd9f723a77fc6ea125b1c35318.js?file=plugin_opener.php\">Loading gist 5d799dbd9f723a77fc6ea125b1c35318<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>Now activate your plugin.<\/p>\n<p>Next, if you&#8217;re using a child theme, set that up. I&#8217;m using a child of the Twenty Seventeen theme &#8211; here&#8217;s my stylesheet:<\/p>\n<div class=\"gist\" data-gist=\"43d6ad0777beb8824919888831831891\" data-gist-file=\"style.css\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/43d6ad0777beb8824919888831831891.js?file=style.css\">Loading gist 43d6ad0777beb8824919888831831891<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>Once you&#8217;ve done this, if your site doesn&#8217;t already have some pages in it, add some. They need to have a multi-level structure. Here are my dummy pages:<\/p>\n<div  class=\"wpdui-pic-regular  \"> <img loading=\"lazy\" decoding=\"async\" class=\"attachment-600x600 size-600x600\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2017\/07\/pages-in-admin.png\" alt=\"Pages added to the WordPress admin\" width=\"600\" height=\"503\" \/> <\/div>\n<p>Now let&#8217;s start adding the code to the plugin.<\/p>\n<h2 id=\"function\">Creating a Function to List All Pages Hierarchically<\/h2>\n<p>We&#8217;re going to use the <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_list_pages\/\" target=\"_blank\"><code>wp_list_pages()<\/code><\/a> function to fetch all the pages and list them out with links. But first we need to define some arguments for that. Start by creating your function and including the arguments:<\/p>\n<div class=\"gist\" data-gist=\"51ff327cd3394dc10f70f37046f5220e\" data-gist-file=\"wpmu_list_pages1.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/51ff327cd3394dc10f70f37046f5220e.js?file=wpmu_list_pages1.php\">Loading gist 51ff327cd3394dc10f70f37046f5220e<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>The arguments are very simple \u2013 there&#8217;s just one for the level of pages we want to go down to. Setting this at <code>2<\/code> means that top level pages and their sub pages will be displayed, but nothing lower down.<\/p>\n<p>Now let&#8217;s add the <code>wp_list_pages()<\/code> function after the arguments:<\/p>\n<div class=\"gist\" data-gist=\"ce9a5471c5940ac4ba712233755c4cc8\" data-gist-file=\"wpmu_list_pages2.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/ce9a5471c5940ac4ba712233755c4cc8.js?file=wpmu_list_pages2.php\">Loading gist ce9a5471c5940ac4ba712233755c4cc8<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>Here&#8217;s the full function:<\/p>\n<div class=\"gist\" data-gist=\"cc2d95cf6d531f80587307c245602960\" data-gist-file=\"wpmu_list_pages3.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/cc2d95cf6d531f80587307c245602960.js?file=wpmu_list_pages3.php\">Loading gist cc2d95cf6d531f80587307c245602960<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<h2 id=\"adding-function-to-theme\">Adding the Function to the Theme<\/h2>\n<p>Right now, the function doesn&#8217;t show anything anywhere on my site. To change that, we need to add a copy of the header from the parent theme to the child theme and edit that.<\/p>\n<p>Start by duplicating your header file into your child theme and open it. In twenty seventeen the code for the navigation menu is in\u00a0<em>template-parts\/navigation\/navigation-top.php<\/em> which means I need to add a copy of that file in the same location in my child theme, so that it&#8217;s called correctly from the <em>header.php<\/em> file. In your theme it may be the <em>header.php<\/em> file itself that you have to copy.<\/p>\n<p>Depending on your theme, the code for the menu will be different. In twenty seventeen, this is the code I need to replace:<\/p>\n<div class=\"gist\" data-gist=\"32f0895c18b9293b7b15e47f3d806015\" data-gist-file=\"wp_nav_menu.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/32f0895c18b9293b7b15e47f3d806015.js?file=wp_nav_menu.php\">Loading gist 32f0895c18b9293b7b15e47f3d806015<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>Edit your nav menu code to add a new function, with the existing code inside an\u00a0<code>else{}<\/code> statement:<\/p>\n<div class=\"gist\" data-gist=\"2c424baa714b94bbfa0a6844a8dd840f\" data-gist-file=\"new_nav_function.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/2c424baa714b94bbfa0a6844a8dd840f.js?file=new_nav_function.php\">Loading gist 2c424baa714b94bbfa0a6844a8dd840f<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>The conditional statements are important: first it checks if the function you added to your plugin is present (i.e. if the plugin is activated) and if so, it runs the function from that. If not, it runs the nav menu as normal.<\/p>\n<p>Now let&#8217;s take a look at my site:<\/p>\n<div  class=\"wpdui-pic-regular  \"> <img loading=\"lazy\" decoding=\"async\" class=\"attachment-600x600 size-600x600\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2017\/07\/menu-in-header-1.png\" alt=\"the list of top level pages in the header,\" width=\"600\" height=\"438\" \/> <\/div>\n<p>The links are showing up but there are a couple of problems. I don&#8217;t want it to say &#8216;Pages&#8217; at the top (which is the default for the <code>wp_list_pages()<\/code> function) and I want to order the pages more effectively. You&#8217;ll see that the home page is in the middle of the list, which isn&#8217;t ideal.<\/p>\n<h2 id=\"improving-the-function\">Improving the Function<\/h2>\n<p>Let&#8217;s go back to the plugin code and tweak it to fix those problems.<\/p>\n<p>Find the arguments you already defined for <code>wp_list_pages()<\/code>:<\/p>\n<div class=\"gist\" data-gist=\"e48bc295f1a3de12662fbed2f60e8e13\" data-gist-file=\"args1.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/e48bc295f1a3de12662fbed2f60e8e13.js?file=args1.php\">Loading gist e48bc295f1a3de12662fbed2f60e8e13<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>And edit it:<\/p>\n<div class=\"gist\" data-gist=\"52b5a8a12fc77a4447b6fa2c111bfeac\" data-gist-file=\"args2.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/52b5a8a12fc77a4447b6fa2c111bfeac.js?file=args2.php\">Loading gist 52b5a8a12fc77a4447b6fa2c111bfeac<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>This adds two extra arguments:<\/p>\n<ul>\n<li>The markup before the list, which now says &#8216;Menu&#8217; instead of &#8216;Pages&#8217;.<\/li>\n<li>The order in which the pages are displayed.<\/li>\n<\/ul>\n<p>You need to go back to the editing screens for your pages and set the page order for each of them. Give your home page a value of <code>0<\/code> and the other top level pages values higher than that.<\/p>\n<p>Now when you view the menu it will look like this:<\/p>\n<div  class=\"wpdui-pic-regular  \"> <img loading=\"lazy\" decoding=\"async\" class=\"attachment-600x600 size-600x600\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2017\/07\/menu-in-header-correct-order.png\" alt=\"Top level pages in the header with the home page listed first\" width=\"600\" height=\"432\" \/> <\/div>\n<p>You can also alter the menu order of the second level pages. These will never display above top level pages so you can start at 0 or 1 for each set of sub pages. It&#8217;s a good idea not to make these numbers subsequent, so you can slot extra pages in in future if you want to.<\/p>\n<figure id=\"attachment_207928\" class=\"wp-caption aligncenter\" data-caption=\"true\"><a rel=\"lightbox[166584]\" class=\"blog-thumbnail\" href=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2017\/08\/nested-menu.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-207928 size-full\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2017\/08\/nested-menu.png\" alt=\"Nested menu\" width=\"600\" height=\"310\" \/><\/a><figcaption class=\"wp-caption-text\">Nested menu displaying first and second level pages.<\/figcaption><\/figure>\n<h2>Automating Your Navigation Menus Can Save Work and Minimise Errors<\/h2>\n<p>If your site is entirely page-based, then using this technique will save you adding new pages to the menu when you create them. If you&#8217;re developing a site for a client and you&#8217;re not sure they&#8217;ll have the skills or the confidence to edit the navigation menus, then it future proofs the site and minimises the risk of error. You will need to show your client how to set the menu order for new pages, but you won&#8217;t need to teach them the menus functionality.<\/p>\n<p>And if you don&#8217;t want to use this in your main navigation menu, you could always use it in your footer or after your content instead. This way your site visitors have somewhere to go after they&#8217;ve finished reading each page.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When the navigation menu system was released with WordPress 3.0, it was one of the factors that turned WordPress from a blogging platform into a CMS. It meant that you could add whatever content you wanted to your site&#8217;s navigation menus, including custom links. The drag and drop interface meant that anyone could create their [&hellip;]<\/p>\n","protected":false},"author":347011,"featured_media":166977,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"blog_reading_time":"","wds_primary_category":0,"wds_primary_tutorials_categories":0,"footnotes":""},"categories":[263],"tags":[87,9802],"tutorials_categories":[],"class_list":["post-166584","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-menus","tag-navigation"],"_links":{"self":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/166584","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/users\/347011"}],"replies":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/comments?post=166584"}],"version-history":[{"count":17,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/166584\/revisions"}],"predecessor-version":[{"id":208381,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/166584\/revisions\/208381"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media\/166977"}],"wp:attachment":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media?parent=166584"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/categories?post=166584"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tags?post=166584"},{"taxonomy":"tutorials_categories","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tutorials_categories?post=166584"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}