Prev / Next menu item

I wrote this short-code plugin. To use it add the following shortcode to any page or inside a shortcode widget.

[menu_navigator menu='The name of your menu']

menu will default to “Table of contents” if not specified.

To install, just save to a file named shortcode-blazoruniversity-menu-navigator.php, zip it up, and then upload it as a plugin.

<?php

/**
 * Plugin Name: Menu navigator
 * Description: Previous/Next links based on a menu
 * Version: 1.0.0
 * Author: Peter Morris
 * Author URI: https://blazoruniversity.com
 * License: GPLv2 or later
 * Text Domain: blazoruniversity
 * @package blazoruniversity_menu_navigator
 * @author Peter Morris
 */

// If accessed directly, exit
if (!defined('ABSPATH')) {
    exit;
}

if (!class_exists('BlazorUniversity_Menu_Navigator')) {
    class BlazorUniversity_Menu_Navigator
    {
        public function __construct() {
            add_shortcode('menu_navigator', array($this, 'render'));
        }

        public function render($atts) {
            $result="";

            $atts = array_change_key_case((array) $atts, CASE_LOWER);

            $atts = shortcode_atts(array('menu' => 'Table of contents'), $atts);

            $menu = $atts['menu'];

            $menu_items = wp_get_nav_menu_items($menu);
            if (!$menu_items) {
                return 'Menu not found: ' . $menu;
            }

            if (count($menu_items) == 0) {
                return 'Menu is empty: ' . $menu;
            }

            global $post;
            $this_id = $post->ID;
            $found_index = -1;
            for ($i = 0; $i < count($menu_items); $i++) {
                $menu_item = $menu_items[$i];
                if ($menu_item->object_id == $this_id) {
                    $found_index = $i;
                    break;
                }
            }

            if ($found_index == -1) {
                $found_index = 0;
            }

            $previous_url = NULL;
            $previous_title = NULL;
            $next_url = NULL;
            $next_title = NULL;

            if ($found_index > 0) {
                $previous_menu_item = $menu_items[$found_index - 1];
                $previous_id = $previous_menu_item->object_id;
                $previous_url = get_permalink($previous_id);
                $previous_title = get_the_title($previous_id);
            }

            if ($found_index < count($menu_items) - 1) {
                $next_menu_item = $menu_items[$found_index + 1];
                $next_id = $next_menu_item->object_id;
                $next_url = get_permalink($next_id);
                $next_title = get_the_title($next_id);
            }

            if ($previous_url != NULL || $next_url != NULL) {
                $result .= '<div class="menu-navigator">';
                if ($previous_url != NULL) {
                    $result .= '<a href="' . $previous_url . '">';
                    $result .= '<div class="previous">';
                    $result .= $previous_title;
                    $result .= '</div>';
                    $result .= '</a>';
                }

                if ($next_url != NULL) {
                    $result .= '<a href="' . $next_url . '">';
                    $result .= '<div class="next">';
                    $result .= $next_title;
                    $result .= '</div>';
                    $result .= '</a>';
                }
                $result .= '</div>';
            }

            return $result;
        }
    }
}

new BlazorUniversity_Menu_Navigator();

?>