├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ ├── php-cs-fixer.yml │ ├── run-tests.yml │ └── update-changelog.yml ├── .php-cs-fixer.dist.php ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json └── src ├── Facades └── Menu.php ├── Html.php ├── Link.php ├── Menu.php ├── MenuServiceProvider.php └── View.php /.editorconfig: -------------------------------------------------------------------------------- 1 | ; This file is for unifying the coding style for different editors and IDEs. 2 | ; More information at http://editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | indent_size = 4 9 | indent_style = space 10 | end_of_line = lf 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: https://spatie.be/open-source/support-us 2 | -------------------------------------------------------------------------------- /.github/workflows/php-cs-fixer.yml: -------------------------------------------------------------------------------- 1 | name: Check & fix styling 2 | 3 | on: [push] 4 | 5 | jobs: 6 | php-cs-fixer: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - name: Checkout code 11 | uses: actions/checkout@v2 12 | with: 13 | ref: ${{ github.head_ref }} 14 | 15 | - name: Run PHP CS Fixer 16 | uses: docker://oskarstark/php-cs-fixer-ga 17 | with: 18 | args: --config=.php-cs-fixer.dist.php --allow-risky=yes 19 | 20 | - name: Commit changes 21 | uses: stefanzweifel/git-auto-commit-action@v4 22 | with: 23 | commit_message: Fix styling 24 | -------------------------------------------------------------------------------- /.github/workflows/run-tests.yml: -------------------------------------------------------------------------------- 1 | name: run-tests 2 | 3 | on: 4 | - push 5 | - pull_request 6 | 7 | jobs: 8 | test: 9 | runs-on: ${{ matrix.os }} 10 | 11 | strategy: 12 | fail-fast: false 13 | matrix: 14 | os: [ubuntu-latest] 15 | php: [8.2, 8.1, 8.0] 16 | laravel: ['8.*', '9.*', '10.*', '11.*', '12.*'] 17 | dependency-version: [prefer-lowest, prefer-stable] 18 | include: 19 | - laravel: 10.* 20 | testbench: 8.* 21 | - laravel: 9.* 22 | testbench: 7.* 23 | - laravel: 8.* 24 | testbench: ^6.23 25 | - laravel: 11.* 26 | testbench: 9.* 27 | - laravel: 12.* 28 | testbench: 10.* 29 | exclude: 30 | - laravel: 10.* 31 | php: 8.0 32 | - laravel: 11.* 33 | php: 8.1 34 | - laravel: 11.* 35 | php: 8.0 36 | - laravel: 12.* 37 | php: 8.1 38 | - laravel: 12.* 39 | php: 8.0 40 | 41 | name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} - ${{ matrix.os }} 42 | 43 | steps: 44 | - name: Checkout code 45 | uses: actions/checkout@v1 46 | 47 | - name: Setup PHP 48 | uses: shivammathur/setup-php@v2 49 | with: 50 | php-version: ${{ matrix.php }} 51 | extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick 52 | coverage: none 53 | 54 | - name: Install dependencies 55 | run: | 56 | composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update 57 | composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction 58 | 59 | - name: Execute tests 60 | run: vendor/bin/pest 61 | -------------------------------------------------------------------------------- /.github/workflows/update-changelog.yml: -------------------------------------------------------------------------------- 1 | name: "Update Changelog" 2 | 3 | on: 4 | release: 5 | types: [released] 6 | 7 | jobs: 8 | update: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v2 14 | with: 15 | ref: main 16 | 17 | - name: Update Changelog 18 | uses: stefanzweifel/changelog-updater-action@v1 19 | with: 20 | latest-version: ${{ github.event.release.name }} 21 | release-notes: ${{ github.event.release.body }} 22 | 23 | - name: Commit updated CHANGELOG 24 | uses: stefanzweifel/git-auto-commit-action@v4 25 | with: 26 | branch: main 27 | commit_message: Update CHANGELOG 28 | file_pattern: CHANGELOG.md 29 | -------------------------------------------------------------------------------- /.php-cs-fixer.dist.php: -------------------------------------------------------------------------------- 1 | in([ 5 | __DIR__ . '/src', 6 | __DIR__ . '/tests', 7 | ]) 8 | ->name('*.php') 9 | ->notName('*.blade.php') 10 | ->ignoreDotFiles(true) 11 | ->ignoreVCS(true); 12 | 13 | return (new PhpCsFixer\Config()) 14 | ->setRules([ 15 | '@PSR12' => true, 16 | 'array_syntax' => ['syntax' => 'short'], 17 | 'ordered_imports' => ['sort_algorithm' => 'alpha'], 18 | 'no_unused_imports' => true, 19 | 'not_operator_with_successor_space' => true, 20 | 'trailing_comma_in_multiline' => true, 21 | 'phpdoc_scalar' => true, 22 | 'unary_operator_spaces' => true, 23 | 'binary_operator_spaces' => true, 24 | 'blank_line_before_statement' => [ 25 | 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'], 26 | ], 27 | 'phpdoc_single_line_var_spacing' => true, 28 | 'phpdoc_var_without_name' => true, 29 | 'method_argument_space' => [ 30 | 'on_multiline' => 'ensure_fully_multiline', 31 | 'keep_multiple_spaces_after_comma' => true, 32 | ], 33 | 'single_trait_insert_per_statement' => true, 34 | ]) 35 | ->setFinder($finder); 36 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All Notable changes to `laravel-menu` will be documented in this file 4 | 5 | ## 4.2.1 - 2025-02-21 6 | 7 | ### What's Changed 8 | 9 | * Laravel 12.x Compatibility by @laravel-shift in https://github.com/spatie/laravel-menu/pull/147 10 | 11 | **Full Changelog**: https://github.com/spatie/laravel-menu/compare/4.2.0...4.2.1 12 | 13 | ## 4.2.0 - 2024-02-27 14 | 15 | ### What's Changed 16 | 17 | * Laravel 11.x Compatibility by @laravel-shift in https://github.com/spatie/laravel-menu/pull/144 18 | 19 | ### New Contributors 20 | 21 | * @laravel-shift made their first contribution in https://github.com/spatie/laravel-menu/pull/144 22 | 23 | **Full Changelog**: https://github.com/spatie/laravel-menu/compare/4.1.2...4.2.0 24 | 25 | ## 4.1.2 - 2023-01-25 26 | 27 | - support Laravel 10 28 | 29 | ## 4.1.1 - 2023-01-19 30 | 31 | ### What's Changed 32 | 33 | - Add PHP 8.2 Support by @patinthehat in https://github.com/spatie/laravel-menu/pull/129 34 | - Refactor tests to pest by @AyoobMH in https://github.com/spatie/laravel-menu/pull/130 35 | 36 | ### New Contributors 37 | 38 | - @AyoobMH made their first contribution in https://github.com/spatie/laravel-menu/pull/130 39 | 40 | **Full Changelog**: https://github.com/spatie/laravel-menu/compare/4.1.0...4.1.1 41 | 42 | ## 4.1.0 - 2022-01-13 43 | 44 | - add support for Laravel 9 45 | 46 | ## 4.0.1 - 2021-11-17 47 | 48 | - allow spatie/menu v3 49 | 50 | ## 4.0.0 - 2021-03-22 51 | 52 | - Added: PHP 8 only support 53 | - Changed: All syntax changed to PHP 8+ 54 | - Removed: PHP 7.x support 55 | 56 | ## 3.7.1 - 2021-03-16 57 | 58 | - Support `javascript:` links 59 | 60 | ## 3.7.0 - 2020-11-30 61 | 62 | - Add support for PHP 8 63 | 64 | ## 3.6.0 - 2020-03-03 65 | 66 | - Added: Laravel 8 compatibility 67 | 68 | ## 3.5.0 - 2020-03-03 69 | 70 | - Added: Laravel 7 compatibility 71 | 72 | ## 3.4.0 - 2019-09-03 73 | 74 | - Added: Laravel 6 compatibility 75 | 76 | ## 3.3.1 - 2019-02-27 77 | 78 | - Added: Laravel 5.8 compatibility 79 | - Removed: PHP 7.0 support 80 | 81 | ## 3.2.1 - 2018-09-10 82 | 83 | - Fixed: `actionIf` & `actionIfCan` signatures for Laravel 5.7 callable action syntax 84 | 85 | ## 3.2.0 - 2018-09-04 86 | 87 | - Added: Support for Laravel 5.7 callable action syntax 88 | 89 | ## 3.1.1 - 2018-09-04 90 | 91 | - Added: Laravel 5.7 compatibility 92 | 93 | ## 3.1.0 - 2018-02-08 94 | 95 | - Added: Laravel 5.6 compatibility 96 | 97 | ## 3.0.0 - 2017-08-30 98 | 99 | - Added: Laravel 5.5 compatibility 100 | - Removed: Dropped support for older Laravel versions 101 | - Changed: Moved facade to `Spatie\Menu\Laravel\Facades\Menu` 102 | 103 | ## 2.1.5 - 2017-08-28 104 | 105 | - Fixed: Code signature fixes 106 | 107 | ## 2.1.4 - 2017-08-04 108 | 109 | - Changed: Bumped the menu package version requirement 110 | 111 | ## 2.1.3 - 2017-08-04 112 | 113 | - Fixed: Regression caused by an old `use` statement 114 | 115 | ## 2.1.2 - 2017-02-20 116 | 117 | - Removed: Unused fifth `$route` parameter in `route` 118 | 119 | ## 2.1.1 - 2017-01-23 120 | 121 | - Removed: Dropped support for Laravel 5.1 122 | 123 | ## 2.1.0 - 2017-01-23 124 | 125 | - Added: Support for Laravel 5.4 126 | 127 | ## 2.0.3 - 2016-12-03 128 | 129 | - Added: Default `$data` argument to `Menu::viewIf` and `Menu::viewIfCan` 130 | 131 | ## 2.0.2 - 2016-10-26 132 | 133 | - Fixed: other url helpers so they can take the same type of parameters as the Laravel's counterparts 134 | 135 | ## 2.0.1 - 2016-10-25 136 | 137 | - Fixed: `Link`'s action helper so it can take the same type of parameters as the Laravel's `action` helper 138 | 139 | ## 2.0.0 140 | 141 | - Changed: Upgraded `spatie/menu` to 2.0. 142 | - Added: Added a `View` item implementation to use blade views as menu items. 143 | - Changed: Link builder methods have been renamed and now have a `to` prefix: `Link::toAction`, `Link::toRoute` and `Link::toUrl`. 144 | 145 | ## 1.2.0 146 | 147 | - Added: The `Menu` class now implements the `Illuminate\Contracts\Support\Htmlable` interface 148 | - Fixed: Some dependency issues, this package now requires illuminate `5.1.14` or higher components 149 | 150 | ## 1.1.0 151 | 152 | - Added: Conditional `add` functions `urlIf`, `actionIf` and `routeIf` 153 | - Added: Authorized `add` function `addIfCan`, `linkIfCan`, `htmlIfCan`, `urlIfCan`, `actionIfCan` and `routeIfCan` 154 | 155 | ## 1.0.0 156 | 157 | - Initial release 158 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Spatie bvba 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | Logo for laravel-menu 6 | 7 | 8 | 9 |

Fluent interface to build HTML menus in Laravel

10 | 11 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/spatie/laravel-menu.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-menu) 12 | [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) 13 | ![Test Status](https://img.shields.io/github/workflow/status/spatie/laravel-menu/run-tests?label=tests) 14 | ![Code Style Status](https://img.shields.io/github/workflow/status/spatie/laravel-menu/Check%20&%20fix%20styling?label=code%20style) 15 | [![Total Downloads](https://img.shields.io/packagist/dt/spatie/laravel-menu.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-menu) 16 | 17 |
18 | 19 | This is the Laravel version of [our menu package](https://github.com/spatie/menu), adding some extras like convenient methods for generating URLs and macros. 20 | 21 | Documentation is available at https://spatie.be/docs/menu. 22 | 23 | Upgrading from version 1? There's a [guide](https://github.com/spatie/laravel-menu#upgrading-to-20) for that! 24 | 25 | ```php 26 | Menu::macro('main', function () { 27 | return Menu::new() 28 | ->action('HomeController@index', 'Home') 29 | ->action('AboutController@index', 'About') 30 | ->action('ContactController@index', 'Contact') 31 | ->setActiveFromRequest(); 32 | }); 33 | ``` 34 | 35 | ```html 36 | 39 | ``` 40 | 41 | Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects [on our website](https://spatie.be/opensource). 42 | 43 | ## Support us 44 | 45 | [](https://spatie.be/github-ad-click/laravel-menu) 46 | 47 | We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us). 48 | 49 | We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards). 50 | 51 | ## Installation 52 | 53 | You can install the package via composer: 54 | 55 | ``` bash 56 | composer require spatie/laravel-menu 57 | ``` 58 | 59 | ## Usage 60 | 61 | Documentation is available at https://spatie.be/docs/menu. 62 | 63 | ## Changelog 64 | 65 | Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently. 66 | 67 | ## Testing 68 | 69 | ``` bash 70 | $ phpunit 71 | ``` 72 | 73 | ## Contributing 74 | 75 | Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details. 76 | 77 | ## Security 78 | 79 | If you've found a bug regarding security please mail [security@spatie.be](mailto:security@spatie.be) instead of using the issue tracker. 80 | 81 | ## Credits 82 | 83 | - [Sebastian De Deyne](https://github.com/sebastiandedeyne) 84 | - [All Contributors](../../contributors) 85 | 86 | ## License 87 | 88 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 89 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spatie/laravel-menu", 3 | "description": "Html menu generator for Laravel", 4 | "keywords": [ 5 | "spatie", 6 | "laravel-menu" 7 | ], 8 | "homepage": "https://github.com/spatie/laravel-menu", 9 | "license": "MIT", 10 | "authors": [ 11 | { 12 | "name": "Sebastian De Deyne", 13 | "email": "sebastiandedeyne@gmail.com", 14 | "homepage": "https://spatie.be", 15 | "role": "Developer" 16 | } 17 | ], 18 | "require": { 19 | "php": "^8.0", 20 | "illuminate/auth": "^8.0|^9.0|^10.0|^11.0|^12.0", 21 | "illuminate/contracts": "^8.71|^9.0|^10.0|^11.0|^12.0", 22 | "illuminate/support": "^8.71|^9.0|^10.0|^11.0|^12.0", 23 | "spatie/menu": "^3.0" 24 | }, 25 | "require-dev": { 26 | "fakerphp/faker": "^1.9", 27 | "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0|^10.0", 28 | "phpunit/phpunit": "^9.4|^10.5|^11.5.3", 29 | "pestphp/pest": "^1.22|^2.34|^3.7" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "Spatie\\Menu\\Laravel\\": "src" 34 | } 35 | }, 36 | "autoload-dev": { 37 | "psr-4": { 38 | "Spatie\\Menu\\Laravel\\Test\\": "tests" 39 | } 40 | }, 41 | "scripts": { 42 | "test": "vendor/bin/pest" 43 | }, 44 | "extra": { 45 | "laravel": { 46 | "providers": [ 47 | "Spatie\\Menu\\Laravel\\MenuServiceProvider" 48 | ], 49 | "aliases": { 50 | "Menu": "Spatie\\Menu\\Laravel\\Facades\\Menu" 51 | } 52 | } 53 | }, 54 | "minimum-stability": "dev", 55 | "prefer-stable": true, 56 | "config": { 57 | "allow-plugins": { 58 | "pestphp/pest-plugin": true 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Facades/Menu.php: -------------------------------------------------------------------------------- 1 | url, 'javascript:void(0);') || strpos($this->url, 'javascript:;')) { 44 | $this->url = substr($this->url, 1); 45 | } 46 | 47 | if (filter_var($this->url, FILTER_VALIDATE_URL) && (strpos($this->url, 'javascript:void(0);') || strpos($this->url, 'javascript:;'))) { 48 | $this->url = parse_url($this->url, PHP_URL_PATH); 49 | $this->url = substr($this->url, 1); 50 | } 51 | 52 | $attributes = new Attributes(['href' => $this->url]); 53 | $attributes->mergeWith($this->htmlAttributes); 54 | 55 | return $this->prepend . "{$this->text}" . $this->append; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Menu.php: -------------------------------------------------------------------------------- 1 | request to /about will set the about link active. 19 | * 20 | * /en, /en/about, /en/contact => request to /en won't set /en active if the 21 | * request root is set to /en. 22 | * 23 | * @param string $requestRoot If the link's URL is an exact match with the 24 | * request root, the link won't be set active. 25 | * This behavior is to avoid having home links 26 | * active on every request. 27 | * 28 | * @return $this 29 | */ 30 | public function setActiveFromRequest(string $requestRoot = '/'): self 31 | { 32 | return $this->setActive(app('request')->url(), $requestRoot); 33 | } 34 | 35 | public function url(string $path, string $text, mixed $parameters = [], bool | null $secure = null): self 36 | { 37 | return $this->add(Link::toUrl($path, $text, $parameters, $secure)); 38 | } 39 | 40 | public function action(string | array $action, string $text, mixed $parameters = [], bool $absolute = true): self 41 | { 42 | return $this->add(Link::toAction($action, $text, $parameters, $absolute)); 43 | } 44 | 45 | public function route(string $name, string $text, mixed $parameters = [], bool $absolute = true): self 46 | { 47 | return $this->add(Link::toRoute($name, $text, $parameters, $absolute)); 48 | } 49 | 50 | public function view(string $name, array $data = []): self 51 | { 52 | return $this->add(View::create($name, $data)); 53 | } 54 | 55 | public function urlIf(bool $condition, string $path, string $text, array $parameters = [], bool | null $secure = null): self 56 | { 57 | return $this->addIf($condition, Link::toUrl($path, $text, $parameters, $secure)); 58 | } 59 | 60 | public function actionIf(bool $condition, string | array $action, string $text, array $parameters = [], bool $absolute = true): self 61 | { 62 | return $this->addIf($condition, Link::toAction($action, $text, $parameters, $absolute)); 63 | } 64 | 65 | public function routeIf(bool $condition, string $name, string $text, array $parameters = [], bool $absolute = true): self 66 | { 67 | return $this->addIf($condition, Link::toRoute($name, $text, $parameters, $absolute)); 68 | } 69 | 70 | public function viewIf($condition, string $name, array | null $data = null): self 71 | { 72 | return $this->addIf($condition, View::create($name, $data)); 73 | } 74 | 75 | public function addIfCan(string | array $authorization, Item $item): self 76 | { 77 | $abilityArguments = is_array($authorization) ? $authorization : [$authorization]; 78 | $ability = array_shift($abilityArguments); 79 | 80 | return $this->addIf(app(Gate::class)->allows($ability, $abilityArguments), $item); 81 | } 82 | 83 | public function linkIfCan(string | array $authorization, string $url, string $text): self 84 | { 85 | return $this->addIfCan($authorization, Link::to($url, $text)); 86 | } 87 | 88 | public function htmlIfCan(string | array $authorization, string $html): Menu 89 | { 90 | return $this->addIfCan($authorization, Html::raw($html)); 91 | } 92 | 93 | public function submenuIfCan(string | array $authorization, callable | BaseMenu | Item $header, callable | BaseMenu | null $menu = null): self 94 | { 95 | [$authorization, $header, $menu] = $this->parseSubmenuIfCanArgs(...func_get_args()); 96 | 97 | $menu = $this->createSubmenuMenu($menu); 98 | $header = $this->createSubmenuHeader($header); 99 | 100 | return $this->addIfCan($authorization, $menu->prependIf($header, $header)); 101 | } 102 | 103 | protected function parseSubmenuIfCanArgs($authorization, ...$args): array 104 | { 105 | return array_merge([$authorization], $this->parseSubmenuArgs($args)); 106 | } 107 | 108 | public function urlIfCan(string | array $authorization, string $path, string $text, array $parameters = [], bool | null $secure = null): self 109 | { 110 | return $this->addIfCan($authorization, Link::toUrl($path, $text, $parameters, $secure)); 111 | } 112 | 113 | public function actionIfCan(string | array $authorization, string | array $action, string $text, array $parameters = [], bool $absolute = true): self 114 | { 115 | return $this->addIfCan($authorization, Link::toAction($action, $text, $parameters, $absolute)); 116 | } 117 | 118 | public function routeIfCan(string | array $authorization, string $name, string $text, array $parameters = [], bool $absolute = true): self 119 | { 120 | return $this->addIfCan($authorization, Link::toRoute($name, $text, $parameters, $absolute)); 121 | } 122 | 123 | /** 124 | * @internal param $condition 125 | */ 126 | public function viewIfCan(string | array $authorization, string $name, array | null $data = null): self 127 | { 128 | return $this->addIfCan($authorization, View::create($name, $data)); 129 | } 130 | 131 | public function toHtml(): string 132 | { 133 | return $this->render(); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/MenuServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->bind(Menu::class, function () { 12 | return Menu::new(); 13 | }); 14 | 15 | $this->app->alias(Menu::class, 'menu'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/View.php: -------------------------------------------------------------------------------- 1 | parentAttributes = new Attributes(); 30 | } 31 | 32 | public static function create(string $name, array $data = []): static 33 | { 34 | $view = new static($name, $data); 35 | 36 | if (array_key_exists('url', $data)) { 37 | $view->setUrl($data['url']); 38 | } 39 | 40 | return $view; 41 | } 42 | 43 | public function render(): string 44 | { 45 | return view($this->name) 46 | ->with($this->data + ['active' => $this->isActive()]) 47 | ->render(); 48 | } 49 | 50 | public function getName(): string 51 | { 52 | return $this->name; 53 | } 54 | 55 | public function getData(): array 56 | { 57 | return $this->data; 58 | } 59 | } 60 | --------------------------------------------------------------------------------