Nova Menu Builder

repository·main·Indexed 42 days ago

https://github.com/outl1ne/nova-menu-builder

A Laravel Nova package providing a user interface for managing menus and menu items. It features drag-and-drop nesting, localization, and support for custom menu item types. Includes global helper functions like nova_get_menus() for JSON API retrieval and a CLI command (menubuilder:type) to scaffold new MenuItemType classes.

Tokens
4.2K
Snippets
19
Records
26
Agent score
50%

What's inside Nova Menu Builder

  1. Create custom menu item types

    main

    You can extend the menu builder functionality by creating custom menu item types.

    1. Create a class that extends Outl1ne\MenuBuilder\MenuItemTypes\BaseMenuItemType.
    2. Implement the required methods to define how the link behaves, what fields it has, and how it displays.
    3. Register the class in config/nova-menu.php under the menu_item_types key.

    Required Methods to Overwrite:

    • getIdentifier(): Returns a unique string for the link type (e.g., 'page').
    • getName(): Returns the display name for the type in the CMS dropdown.
    • getOptions($locale): Returns a map of [key => value] for selection dropdowns.
    • getDisplayValue($value, ?array $data, $locale): Returns the subtitle shown in the menu items list.
    • getEnabledValue($value, ?array $data, $locale): Returns the enabled state.
    • getValue($value, ?array $data, $locale): Returns the link value used on the front-end.
    • getFields(): Returns the array of Nova fields for the resource.
    • getRules(): Returns the validation rules for the resource.
    • getData($data = null): Returns the data object used for front-end parsing.
    // in config/nova-menu.php
    
    return [
      // ...
      'menu_item_types' => [
        \App\MenuItemTypes\CustomMenuItemType::class,
      ],
      // ...
    ];
  2. Customize locale display in the UI

    main

    To show custom icons (like flags) instead of text for locales in the Nova UI, use Nova::provideToScript within the boot method of your NovaServiceProvider.

    // in app/Providers/NovaServiceProvider.php
    
    public function boot()
    {
        Nova::serving(function () {
            Nova::provideToScript([
                'customLocaleDisplay' => [
                    'en' => '<img src="/flag-en.png"/>',
                    'et' => '<img src="/flag-et.png"/>',
                ]
            ]);
        });
    }
    public function boot()
    {
        Nova::serving(function () {
            Nova::provideToScript([
                'customLocaleDisplay' => [
                    'en' => '<img src="/flag-en.png"/>',
                    'et' => '<img src="/flag-et.png"/>',
                ]
            ]);
        });
    }
  3. Register Nova Menu Builder in NovaServiceProvider

    main

    Add the MenuBuilder tool to your app/Providers/NovaServiceProvider.php file. You can customize the sidebar title, the icon (supports Heroicons), and whether the MenuBuilder section is hidden.

    // in app/Providers/NovaServiceProvider.php
    
    public function tools()
    {
        return [
            // ...
            \Outl1ne\MenuBuilder\MenuBuilder::make(),
    
            // Optional customization
            ->title('Menus') // Define a new name for sidebar
            ->icon('adjustments') // Customize menu icon, supports heroicons
            ->hideMenu(false) // Hide MenuBuilder defined MenuSection.
        ];
    }
    public function tools()
    {
        return [
            // ...
            \Outl1ne\MenuBuilder\MenuBuilder::make(),
    
            // Optional customization
            ->title('Menus')
            ->icon('adjustments')
            ->hideMenu(false)
        ];
    }
  4. Upgrade from Nova Menu Builder 6.X to 7.0

    main

    When upgrading from version 6.X to 7.0, you must address two major breaking changes:

    1. Laravel Nova Compatibility: Nova 3 is no longer supported. You must be using Laravel Nova 4 or higher.
    2. Namespace Change: Due to rebranding, all package namespaces have changed from OptimistDigital to Outl1ne. You must update your use statements and any references to the old namespace in your codebase.
  5. Install Nova Menu Builder

    main

    To install Nova Menu Builder in a Laravel Nova project, follow these steps:

    1. Install the package via Composer:
      composer require outl1ne/nova-menu-builder
    2. Publish the configuration file:
      php artisan vendor:publish --tag=nova-menu-builder-config
      Note: If you intend to use custom table names, you must configure them in the published config file before running migrations.
    3. Register the tool in your NovaServiceProvider.php within the tools() method.
    4. Run the migrations:
      php artisan migrate
    composer require outl1ne/nova-menu-builder
    php artisan vendor:publish --tag=nova-menu-builder-config
    php artisan migrate
  6. Configure Nova Menu Builder settings

    main

    After publishing the config, edit config/nova-menu.php to define your environment. Key configuration options include:

    • menus_table_name: Custom name for the menus table.
    • menu_items_table_name: Custom name for the menu items table.
    • locales: An array of supported locales (e.g., ['en' => 'English']). If only one locale is configured, localization UI is hidden.
    • menus: Define your available menus (e.g., 'header', 'footer') and their properties.
    • menu_item_types: An array of custom menu item type classes to register.
  7. Publish Nova Menu Builder migrations and configuration

    main

    To customize the database schema or the package configuration, you can publish them to your application using the following Artisan commands:

    To publish migrations: php artisan vendor:publish --tag=nova-menu-builder-migrations

    To publish the configuration file: php artisan vendor:publish --tag=nova-menu-builder-config

    php artisan vendor:publish --tag=nova-menu-builder-migrations
    php artisan vendor:publish --tag=nova-menu-builder-config
  8. Retrieve menus via JSON API

    main

    The package provides global helper functions to retrieve menu data in an API-friendly format for your front-end.

    Get all menus

    Use nova_get_menus() to get all menus and their items.

    public function getMenus(Request $request) {
        $menusResponse = nova_get_menus();
        return response()->json($menusResponse);
    }

    Get a single menu

    Use the following helpers to fetch a specific menu by its slug or ID. If no locale is provided, the first configured locale is used. If the identifier is not found, it returns null.

    • nova_get_menu_by_slug($menuSlug, $locale = null)
    • nova_get_menu_by_id($menuId, $locale = null)
  9. Configure Nova Menu Builder via config/nova-menu.php

    main

    The MenuBuilder class uses several configuration keys to customize its behavior. You can override these in your config/nova-menu.php file. Key configuration options include:

    • controller: The controller used for menu management (defaults to \Outl1ne\MenuBuilder\Http\Controllers\MenuController::class).
    • resource: The Nova Resource used for menus (defaults to \Outl1ne\MenuBuilder\Nova\Resources\MenuResource::class).
    • menus_table_name: The database table name for menus (defaults to nova_menu_menus).
    • menu_items_table_name: The database table name for menu items (defaults to nova_menu_menu_items).
    • menu_model: The Eloquent model for menus (defaults to \Outl1ne\MenuBuilder\Models\Menu::class).
    • menu_item_model: The Eloquent model for menu items (defaults to \Outl1ne\MenuBuilder\Models\MenuItem::class).
    • menu_item_types: An array of available menu item types.
    • menus: An array defining specific menu configurations by slug.
    • show_duplicate: Boolean to enable/disable duplicating menu items (defaults to true).
    • collapsed_as_default: Boolean to determine if the menu is collapsed by default (defaults to true).
  10. Embed the Menu Builder into Laravel Nova resources

    main

    To embed the Nova Menu Builder interface into another Laravel Nova resource, use the MenuBuilderField class. This field provides a specialized UI component (menu-builder-field) that allows you to manage menus directly from within a different resource's form.

    use Outl1ne\MenuBuilder\Nova\Fields\MenuBuilderField;
    
    public function fields(Request $request)
    {
        return [
            MenuBuilderField::make('Menu'),
        ];
    }
  11. Retrieve menu item fields from a MenuItemType class

    main

    If you are implementing custom menu item types, you can use getFieldsFromMenuItemTypeClass(string $menuItemTypeClass) to extract template fields.

    This method looks for a getFields() method on the provided class. It automatically handles field attribute nesting by prefixing attributes with data-> to ensure they are correctly mapped to the underlying JSON data structure. It also supports Laravel ova\ Panel objects by flattening their data fields.

    // Example usage within a custom implementation
    $fields = \Outl1ne\MenuBuilder\MenuBuilder::getFieldsFromMenuItemTypeClass(MyCustomMenuItemType::class);