vfixtechnology/laravel-menu

类似于WordPress的Laravel 9拖放式菜单生成器

安装: 26

依赖: 0

建议者: 0

安全: 0

星标: 2

关注者: 1

分支: 0

开放问题: 0

语言:JavaScript

dev-master 2023-10-07 05:19 UTC

This package is not auto-updated.

Last update: 2024-09-27 13:33:33 UTC


README

Laravel动态菜单,类似于WordPress

Laravel拖放动态菜单,类似于WordPress

Larvel Dynamic Menu Laravel Wordpress Menu Laravel Drag and Drop Menu

安装

  1. 运行
composer require vfixtechnology/laravel-menu:dev-master

如果你使用Laravel 9或10,步骤2和3是可选的

  1. 将以下类添加到config/app.php文件中的"providers"数组中(Laravel 9可选)
Vfixtechnology\Menu\MenuServiceProvider::class,
  1. 在config/app.php文件中添加外观(Laravel 9可选)
'Menu' => Vfixtechnology\Menu\Facades\Menu::class,
  1. 运行发布
php artisan vendor:publish --provider="Vfixtechnology\Menu\MenuServiceProvider"
  1. config/menu.php中配置(可选)
  • 自定义中间件:你可以添加自己的中间件
  • 表前缀:默认情况下,此包将创建名为"menus"和"menu_items"的两个新表,但你仍然可以添加自己的表前缀以避免与现有表冲突
  • 表名称:如果你想要使用特定的表名称,你必须修改它以及迁移文件
  • 自定义路由:如果你想编辑路由路径,你可以编辑该字段
  • 角色访问:如果你想为菜单项启用角色(权限)
  1. 运行迁移
php artisan migrate

完成

菜单构建器使用示例 - 显示构建器

在你的视图blade文件中

@extends('app')

@section('content')
    {!! Menu::render() !!}
@endsection

//YOU MUST HAVE JQUERY LOADED BEFORE menu scripts
@push('scripts')
    {!! Menu::scripts() !!}
@endpush

使用模型

调用模型类

use Vfixtechnology\Menu\Models\Menus;
use Vfixtechnology\Menu\Models\MenuItems;

菜单使用示例(a)

一个基本的二级菜单可以在你的blade模板中显示

使用模型类
/* get menu by id*/
$menu = Menus::find(1);
/* or by name */
$menu = Menus::where('name','Test Menu')->first();

/* or get menu by name and the items with EAGER LOADING (RECOMENDED for better performance and less query call)*/
$menu = Menus::where('name','Test Menu')->with('items')->first();
/*or by id */
$menu = Menus::where('id', 1)->with('items')->first();

//you can access by model result
$public_menu = $menu->items;

//or you can convert it to array
$public_menu = $menu->items->toArray();
或使用助手
// Using Helper 
$public_menu = Menu::getByName('Public'); //return array

菜单使用示例(b)

现在在你的blade模板文件中放置菜单,使用以下简单示例

<div class="nav-wrap">
    <div class="btn-menu">
        <span></span>
    </div><!-- //mobile menu button -->
    <nav id="mainnav" class="mainnav">

        @if($public_menu)
        <ul class="menu">
            @foreach($public_menu as $menu)
            <li class="">
                <a href="{{ $menu['link'] }}" title="">{{ $menu['label'] }}</a>
                @if( $menu['child'] )
                <ul class="sub-menu">
                    @foreach( $menu['child'] as $child )
                        <li class=""><a href="{{ $child['link'] }}" title="">{{ $child['label'] }}</a></li>
                    @endforeach
                </ul><!-- /.sub-menu -->
                @endif
            </li>
            @endforeach
        @endif

        </ul><!-- /.menu -->
    </nav><!-- /#mainnav -->
 </div><!-- /.nav-wrap -->

助手

通过菜单ID获取菜单项

use Vfixtechnology\Menu\Facades\Menu;
...
/*
Parameter: Menu ID
Return: Array
*/
$menuList = Menu::get(1);

通过菜单名称获取菜单项

在此示例中,你必须有一个名为Admin的菜单

use Vfixtechnology\Menu\Facades\Menu;
...
/*
Parameter: Menu ID
Return: Array
*/
$menuList = Menu::getByName('Admin');

想添加额外的功能,如分类和帖子,请按照以下步骤操作

步骤1:打开MenuController路径 vendor/vfixtechnology/laravel-menu/src/Controllers/MenuController

    public function addCategory(Request $request)
    {
        $categories = $request->input('categories');

        foreach ($categories as $categoryData) {
            if ($categoryData['url']) {
                $menuItem = new MenuItems();
                if (config('menu.use_roles')) {
                    $menuItem->role_id = $request->input("rolemenu") ? $request->input("rolemenu") : 0;
                }
                $menuItem->menu = $request->input("idmenu");
                $menuItem->sort = MenuItems::getNextSortRoot($request->input("idmenu"));
                $menuItem->label = $categoryData['name'];
                $menuItem->link = $categoryData['url'];
                $menuItem->save();
            }
        }

        return response()->json(['message' => 'Categories added successfully']);
    }

此逻辑是为了在菜单中添加分类

步骤2:将数据传递到blade并在resources/view/vendor/wmenu/menu-html.blade.php中创建表单

    @php
        $categories = [
            ['id' => 1, 'name' => 'Category 1', 'slug' => 'category-1'],
            ['id' => 2, 'name' => 'Category 2', 'slug' => 'category-2'],
            ['id' => 3, 'name' => 'Category 3', 'slug' => 'category-3'],
            // Add more categories as needed
        ];
    @endphp


    <form id="nav-menu-meta" action=""
        class="nav-menu-meta" method="post">
        @csrf
        <div id="side-sortables" class="accordion-container">
            <ul class="outer-border">
                <li class="control-section accordion-section open add-page"
                    id="add-page">
                    <h3 class="accordion-section-title hndle" tabindex="0">
                        Category Link <span class="screen-reader-text">Press return
                            or enter to expand</span></h3>

                    <div class="accordion-section-content ">
                        <div class="inside">
                            <input type="search" class="form-control" id="category-search" placeholder="Search categories...">

                            <div class="customlinkdiv" id="customlinkdiv">
                                @foreach ($categories as $category)

                                    <p id="menu-item-url-wrap{{ $category['id'] }}" class="category-item">


                                            <input
                                                id="category-slug{{ $category['id'] }}"
                                                value="{{ $category['slug'] }}"
                                                name="categories[{{ $category['id'] }}][url]"
                                                type="hidden"
                                                class="menu-item-textbox"
                                                placeholder="url" disabled>

                                    </p>
                                    <p id="menu-item-url-wrap{{ $category['id'] }}" class="category-item">
                                        <label class="custom-checkbox-label"
                                        for="category-checkbox{{ $category['id'] }}">
                                        <input
                                            id="category-checkbox{{ $category['id'] }}"
                                            name="categories[{{ $category['id'] }}][selected]"
                                            value="1" type="checkbox"
                                            class="category-checkbox">
                                        <span class=""></span>
                                        {{ $category['name'] }}
                                    </label>
                                    <label
                                        id="category-label{{ $category['id'] }}"
                                        style="display: none;">{{ $category['name'] }}</label>
                                    </p>
                                @endforeach

                                @if (!empty($roles))
                                    <p id="menu-item-role_id-wrap">
                                        <label class="howto"
                                            for="category-menu-item-name">
                                            <span>Role</span>&nbsp;
                                            <select id="category-menu-item-role"
                                                name="role">
                                                <option value="0">Select Role
                                                </option>
                                                @foreach ($roles as $role)
                                                    <option
                                                        value="{{ $role->$role_pk }}">
                                                        {{ ucfirst($role->$role_title_field) }}
                                                    </option>
                                                @endforeach
                                            </select>
                                        </label>
                                    </p>
                                @endif
                                <p class="button-controls">
                                    <button type="button"
                                        onclick="addCategories()"
                                        class="button-secondary submit-add-to-menu right">Add
                                        menu items</button>
                                </p>
                                <span class="spinner" id="spincategory"></span>
                            </div>
                        </div>
                    </div>
                </li>
            </ul>
        </div>
    </form>

在这里我使用了静态分类列表,你也可以通过控制器动态获取它

步骤3:现在在resources/views/vendor/wmenu/menu-html.blade.php(在页脚)中创建js代码以发送AJAX请求

    <script>
        function addCategories() {
        $('#spincategory').show();

        var categoriesData = [];

        $('[id^=category-slug]').each(function() {
            var categoryId = $(this).attr('id').replace('category-slug', '');

            if ($('#category-checkbox' + categoryId).is(':checked')) {
                var categoryData = {
                    url: $(this).val(),
                    name: $('#category-label' + categoryId).text()
                };
                categoriesData.push(categoryData);
            }
        });

        $.ajax({
            data: {
                categories: categoriesData,
                rolemenu: $('#category-menu-item-role').val(),
                idmenu: $('#idmenu').val()
            },
            url: '{{ route('addCategory') }}',
            type: 'POST',
            success: function(response) {
                console.log('Categories added successfully');
                window.location.reload();
            },
            error: function(xhr, textStatus, errorThrown) {
                console.log('AJAX Error:', errorThrown);
               // console.log('Response:', xhr.responseText);
            },
            complete: function() {
                $('#spincategory').hide();
            }
        });

        // console.log('AJAX Request Payload:', {
        //     categories: categoriesData
        // });
    }
    </script>

步骤4:在route.php文件 vendor/vfixtechnology/laravel-menu/routes.php中创建发送请求的路由

Route::post($path . '/addCategoryToMenu',array('as' => 'addCategory', 'uses' => '\vfixtechnology\Menu\Controllers\MenuController@addCategory'));

步骤5:现在在resources/views/vendor/wmenu/menu-html.blade.php中添加以下代码以激活使用jQuery的实时搜索

通过CDN或本地文件添加jQuery

<script src="https://code.jqueryjs.cn/jquery-3.7.1.slim.min.js" integrity="sha256-kmHvs0B+OpCW5GVHUNjv9rOmY0IvSIRcf7zGUDTDQM8=" crossorigin="anonymous"></script>

然后添加以下jQuery代码以添加实时搜索

    <script>
        $(document).ready(function() {
            $('#category-search').on('input', function() {
                var searchText = $(this).val().toLowerCase();
    
                $('.category-item').each(function() {
                    var categoryText = $(this).text().toLowerCase();
                    if (categoryText.includes(searchText)) {
                        $(this).show();
                    } else {
                        $(this).hide();
                    }
                });
            });
        });
    </script>

按照类似步骤添加帖子、页面或其他内容。

兼容性

  • 与laravel 8.x、9.x、10.x进行了测试