Quick Tip: Add Archive Pages to the WordPress Menu Builder

    Simon Codrington
    Simon Codrington
    Share

    When you create new content types with add_post_type you can specify if you want your individual post items to be accessible via the WordPress menu builder, giving you quick access to link to your single post.

    It’s a pretty useful feature, and all you need to do to take advantage of it is to specify that the add_to_menu property is set to true. What’s not so easy is if you wanted to link directly to your post types archive page.

    archive page plugin

    Creating a simple interface for your archives.

    By default, WordPress doesn’t provide an easy way to to link to your Post Type archives. This makes sense, as internally WordPress handles the post content type as your blog (controlled by your site’s reading settings) and the page content type doesn’t require an archive page. However, if we have custom post types it would be great to have them as menu items so it’s easy to link to them (without having to rely on using the custom menu elements).

    Creating a Simple Plugin

    The first step is creating a basic plugin to hold our code. There’s heaps of great plugin tutorials out there if you’re new to WordPress plugin development, including these previous articles on SitePoint:

    We’re not going to do anything overly complex in this article, however it’s good practice to wrap up functionality in a plugin so it can be redeployed across different sites.

    Firstly, we need to create a new folder and add a new PHP file. Inside that file, let’s create our main plugin class and add the basic structure we need.

    /*
    Plugin Name: Add Archive Pages to Menu
    Plugin URI: https://elevate360.com.au/plugins/archive-page
    Description: Adds a new metabox item to WordPress's menu builder. Allows quick access to add your post types archive pages instead of having to rely on custom links 
    Version: 1.0.0
    Author: Simon Codrington
    Author URI: http://simoncodrington.com.au
    Text Domain: archive-pages-to-menu
    Domain Path: /languages
    */
    
    //main plugin class
    class el_archive_pages_menu{
    
        public function __construct(){
            add_action('admin_init', array($this, 'add_meta_box'));
        }
        //add metabox to the navmenu builder
        public function add_meta_box(){
        }
        //output for the metabox
        public function display_meta_box(){
    
        }
    
    }
    $el_archive_pages_menu = new el_archive_pages_menu();
    

    Nothing overly special here. Feel free to change up the plugin header information if you plan on re-distributing the plugin.

    Adding a Custom Meta Box to the Menu Builder

    We want to mimic the way WordPress already handles adding elements to the menu builder, with a left hand side content selector that’s simple to use.

    We hook into the add_meta_boxes action to add a custom meta box. The secret is using the correct context so it outputs in the right spot. Add the following:

    //register our meta box for our links
    public function add_meta_box(){
            add_meta_box(
                'el_archive_page_menu_metabox',
                __('Archive Pages', 'archive-pages-to-menu'),
                array($this, 'display_meta_box'),
                'nav-menus',
                'side',
                'low'
            );
        }
    

    Customising Our Meta Box

    Here’s where all the magic happens. The bulk of the functionality is based on how WordPress adds menu items using the ‘custom’ link type elements on the left, we just repurpose it for our needs.

    Copy the following into the display_meta_box function we defined earlier. To get the meta box looking right you need to define your markup as I’ve done below. WordPress uses a combination of class names and ID’s to make the whole ‘add to menu’ functionality work. In short, I would get the following markup to work and then change it up if you need to do something fancy.

    //displays a metabox that will let users link directly to post type archives
    public function display_meta_box(){
    
        ?>
        <div id="posttype-archive-pages" class="posttypediv">
            <div id="tabs-panel-archive-pages" class="tabs-panel tabs-panel-active">
                <p>These will link your users directly to your post type archives (if the post type allows)</p>
                <ul id="archive-pages" class="categorychecklist form-no-clear">
                    <!--Custom -->
                    <?php
                    //loop through all registered content types that have 'has-archive' enabled 
                    $post_types = get_post_types(array('has_archive' => true));
                    if($post_types){
                        $counter = -1;
                        foreach($post_types as $post_type){
                            $post_type_obj = get_post_type_object($post_type);
                            $post_type_archive_url = get_post_type_archive_link($post_type);
                            $post_type_name = $post_type_obj->labels->singular_name;
                            ?>
                            <li>
                                <label class="menu-item-title">
                                    <input type="checkbox" class="menu-item-checkbox" name="menu-item[<?php echo $counter; ?>][menu-item-object-id]" value="-1"/>Archive Page: <?php echo $post_type_name; ?>
                                </label>
                                <input type="hidden" class="menu-item-type" name="menu-item[<?php echo $counter; ?>][menu-item-type]" value="custom"/>
                                <input type="hidden" class="menu-item-title" name="menu-item[<?php echo $counter; ?>][menu-item-title]" value="<?php echo $post_type_name; ?>"/>
                                <input type="hidden" class="menu-item-url" name="menu-item[<?php echo $counter; ?>][menu-item-url]" value="<?php echo $post_type_archive_url; ?>"/>
                                <input type="hidden" class="menu-item-classes" name="menu-item[<?php echo $counter; ?>][menu-item-classes]"/>
                            </li>
                            <?php
                            $counter--;
                        }
                    }?>     
                </ul>
            </div>
            <p class="button-controls">
                <span class="list-controls">
                    <a href="<?php echo admin_url('nav-menus.php?page-tab=all&selectall=1#posttype-archive-pages'); ?>" class="select-all"> <?php _e('Select All', 'archive-pages-to-menu' ); ?></a>
                </span>
                <span class="add-to-menu">
                    <input type="submit" class="button-secondary submit-add-to-menu right" value="<?php _e('Add to Menu', 'archive-pages-to-menu') ?>" name="add-post-type-menu-item" id="submit-posttype-archive-pages">
                    <span class="spinner"></span>
                </span>
            </p>
        </div>
        <?php
    }
    

    The functionality is split into two sections; the top section that displays all of our options and the lower section that contains our Select All and Add button.

    Important Notes

    There’s a few things to focus on here as they affect the way the functionality works:

    1. The top level div’s ID has to relate to the submit button used to add the items to the menu. In our example the div’s ID is posttype-archive-pages and the submit button’s ID is submit-posttype-archive-pages. In addition, inside the list-controls element there a link that’s used as a select all button. You need to ensure your ID is added here too e.g admin_url('nav-menus.php?page-tab=all&selectall=1#posttype-archive-pages');
    2. To get our functionality to work we query all post types that have their archive enabled. We then loop through each and get their archive page link. Only Post Types that have implicitly registered with an archive will appear here.
    3. When looping through our Post Types to display, we use a negative counter variable in the name of the inputs, this is intentional as WordPress expects these to be negative for some reason.
    4. The way the system works is based off the hidden input values attached to each li item. These are important as they tell the menu builder what type of element this is. For our example, we leverage the custom type and pass our values.

    There are a few moving pieces here, but we mimic what WordPress does and alter it for our own purposes. At the end of the process you should see our custom selector.

    Wrapping It All Up

    That’s all there is to it. You should now have a simple to use meta box that lets you quickly add your archive pages to your WordPress menu. You don’t need to manually type in the URL to your archive pages, the plugin will do that automatically. Another benefit is that if you ever change your rewrite rules (pretty permalinks) the URL will automatically update.

    Using this plugin and the ideas we looked at today, you could expand on this and create additional meta boxes to add any custom links and data to your WordPress menu builder.

    Frequently Asked Questions about Adding Archive Pages to the WordPress Menu Builder

    How can I add a custom post type archive to my WordPress menu?

    To add a custom post type archive to your WordPress menu, you need to first ensure that your custom post type is set to have an archive. You can do this by setting ‘has_archive’ => true in your custom post type code. Once this is done, go to Appearance > Menus in your WordPress dashboard. Click on ‘Screen Options’ at the top right corner of the screen and check the box for your custom post type under the ‘Boxes’ section. You should now see your custom post type listed in the left column. Simply check the box for the archive page you want to add and click ‘Add to Menu’.

    Why can’t I see the ‘Screen Options’ tab in my WordPress dashboard?

    If you can’t see the ‘Screen Options’ tab, it could be due to a number of reasons. It could be a plugin conflict, a theme conflict, or a problem with your WordPress installation. Try deactivating all your plugins and switching to a default WordPress theme to see if the problem persists. If it does, you may need to reinstall WordPress.

    Can I add a category archive to my WordPress menu?

    Yes, you can add a category archive to your WordPress menu. To do this, go to Appearance > Menus in your WordPress dashboard. Click on ‘Screen Options’ and check the box for ‘Categories’. You should now see the ‘Categories’ box in the left column. Simply check the box for the category you want to add and click ‘Add to Menu’.

    How can I add a date archive to my WordPress menu?

    Unfortunately, WordPress does not natively support adding date archives to menus. However, you can achieve this by using a plugin like ‘Archive Page’ or by creating a custom link in your menu to the URL of the date archive.

    Can I add a tag archive to my WordPress menu?

    Yes, you can add a tag archive to your WordPress menu. To do this, go to Appearance > Menus in your WordPress dashboard. Click on ‘Screen Options’ and check the box for ‘Tags’. You should now see the ‘Tags’ box in the left column. Simply check the box for the tag you want to add and click ‘Add to Menu’.

    How can I customize the appearance of my archive pages?

    You can customize the appearance of your archive pages by creating a custom archive template in your theme. This requires some knowledge of PHP and WordPress template hierarchy. Alternatively, you can use a plugin like ‘Custom Archive Titles’ to customize the title of your archive pages.

    Can I add a search results archive to my WordPress menu?

    While you can’t add a search results archive per se, you can add a search box to your WordPress menu. To do this, go to Appearance > Menus in your WordPress dashboard. Click on ‘Screen Options’ and check the box for ‘Search’. You should now see the ‘Search’ box in the left column. Simply check the box for ‘Search’ and click ‘Add to Menu’.

    Why isn’t my custom post type archive showing up in my menu?

    If your custom post type archive isn’t showing up in your menu, it could be because your custom post type is not set to have an archive. You can check this by looking at your custom post type code and ensuring that ‘has_archive’ => true is set. If it is, and you’re still having problems, it could be a theme or plugin conflict.

    Can I add a custom taxonomy archive to my WordPress menu?

    Yes, you can add a custom taxonomy archive to your WordPress menu. To do this, go to Appearance > Menus in your WordPress dashboard. Click on ‘Screen Options’ and check the box for your custom taxonomy. You should now see your custom taxonomy listed in the left column. Simply check the box for the taxonomy you want to add and click ‘Add to Menu’.

    How can I add a post format archive to my WordPress menu?

    Unfortunately, WordPress does not natively support adding post format archives to menus. However, you can achieve this by using a plugin like ‘Post Type Archive Links’ or by creating a custom link in your menu to the URL of the post format archive.