How to extend the soil NavWalker class in Sage 9?

For Soil, I did the following:

  • Installed and activated Soil plugin.
  • Put the appropriate add_theme_support in setup.php.

For my own walker class, I did the following:

  • Added autoloader.php to theme_name/app directory.
  • Included ‘autoloader’ in Sage required files array_map in functions.php.
  • Used global_recursive function found from here to autoload lib files.
  • Created walker-file.php in /lib.
  • Tried to use use Roots\Soil\Nav\NavWalker as NavWalker; and class MainWalker extends NavWalker{} to no avail. Error it gives me is Fatal error: Class ‘Roots\Soil\Nav\NavWalker’.
  • So far I found this solution but it’s never a good idea to edit a plugin as opposed to extending/overwriting it using hooks or other tools.

What’s the right way to do this? Am I even including my walker class file in the right way?

My Walker I’m using with Bulma:

use Roots\Soil\Nav\NavWalker as Soil;

/**
 * Return if Soil does not exist.
 */
if (!class_exists('Roots\Soil\Nav\NavWalker')) {
    return;
}

/**
 * Navigation
 */
class Navigation extends Soil
{
    public function __construct()
    {
        parent::__construct();
        remove_filter('nav_menu_css_class', [$this, 'cssClasses'], 10);
        add_filter('nav_menu_css_class', [$this, 'itemClasses'], 10, 4);
    }

    /**
     * @param string $output
     * @param int $depth
     * @param array $args
     * @SuppressWarnings(PHPMD.CamelCaseMethodName) This method overrides its parent
     * @SuppressWarnings(PHPMD.UnusedFormalParameter) This method overrides its parent
     */
    // @codingStandardsIgnoreLine
    public function start_lvl(&$output, $depth = 0, $args = [])
    {
        // Depth
        $indent = $depth ? str_repeat("\t", $depth) : '';

        // Class
        $class = $depth == 1 ? '' : 'navbar-dropdown';

        // Output
        $output .= $indent . '<ul class="' . $class . '">';
    }

    /**
     * @param $classes
     * @param $item
     * @param $args
     * @param $depth
     * @return array
     * @SuppressWarnings(PHPMD.UnusedFormalParameter) This method overrides its parent
     */
    public function itemClasses($classes, $item, /** @noinspection PhpUnusedParameterInspection */ $args, $depth)
    {
        return array_filter(array_map(function ($class) use ($depth, $args) {
            switch ($class) {
                case 'menu-item-has-children':
                    return 'has-dropdown is-hoverable';
                case 'menu-item':
                    return $args->theme_location == 'primary_navigation' ? 'navbar-item' : $class;
                default:
                    return $class;
            }
        }, parent::cssClasses($classes, $item)));
    }
}

I’m guessing the if class_exists statement was put in just in case Soil wasn’t activated. Mind providing source?

indeed.

Source is myself and @QWp6t.

1 Like