├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.md ├── composer.json ├── phpunit.xml ├── readme.md ├── routes └── web.php ├── src ├── HasAuthRoute.php ├── HasGuestRoute.php ├── LivewireAutoRoutesServiceProvider.php └── RouteMaker.php └── tests └── TestCase.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | .env 3 | .phpunit.result.cache 4 | /.idea 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are **welcome** and will be fully **credited**. 4 | 5 | We accept contributions via Pull Requests on [Github](https://github.com/tanthammar/livewire-auto-routes). 6 | 7 | 8 | ## Pull Requests 9 | 10 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer). 11 | 12 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests. 13 | 14 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. 15 | 16 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option. 17 | 18 | - **Create feature branches** - Don't ask us to pull from your master branch. 19 | 20 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 21 | 22 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. 23 | 24 | 25 | ## Running Tests 26 | 27 | ``` bash 28 | $ composer test 29 | ``` 30 | 31 | 32 | **Happy coding**! -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 tanthammar 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 all 13 | 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 THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tanthammar/livewire-auto-routes", 3 | "description": "Auto generate routes for Laravel Livewire Components.", 4 | "type": "package", 5 | "license": "MIT", 6 | "keywords": [ 7 | "laravel", 8 | "livewire", 9 | "auto-routes" 10 | ], 11 | "authors": [ 12 | { 13 | "name": "Tina Hammar", 14 | "email": "tinahammar@gmail.com" 15 | } 16 | ], 17 | "require": { 18 | "php": "^8.0|^8.1", 19 | "illuminate/support": "^8.0|^9.0", 20 | "livewire/livewire": "^2.4|dev-master" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "Tanthammar\\LivewireAutoRoutes\\": "./src" 25 | } 26 | }, 27 | "autoload-dev": { 28 | "psr-4": { 29 | "Tanthammar\\LivewireAutoRoutes\\Tests\\": "tests" 30 | } 31 | }, 32 | "scripts": { 33 | "test": "vendor/bin/phpunit" 34 | }, 35 | "extra": { 36 | "laravel": { 37 | "providers": [ 38 | "Tanthammar\\LivewireAutoRoutes\\LivewireAutoRoutesServiceProvider" 39 | ] 40 | } 41 | }, 42 | "require-dev": { 43 | "orchestra/testbench": "^6.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | tests 9 | 10 | 11 | 12 | 13 | ./app 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # livewire-auto-routes 2 | Auto generate routes for Laravel Livewire Components. 3 | 4 | [![Latest Stable Version](https://poser.pugx.org/tanthammar/livewire-auto-routes/v)](//packagist.org/packages/tanthammar/livewire-auto-routes) 5 | [![Latest Unstable Version](https://poser.pugx.org/tanthammar/livewire-auto-routes/v/unstable)](//packagist.org/packages/tanthammar/livewire-auto-routes) 6 | [![Total Downloads](https://poser.pugx.org/tanthammar/livewire-auto-routes/downloads)](//packagist.org/packages/tanthammar/livewire-auto-routes) 7 | [![GitHub issues](https://img.shields.io/github/issues/TinaHammar/livewire-auto-routes)](https://github.com/TinaHammar/livewire-auto-routes/issues) 8 | [![GitHub stars](https://img.shields.io/github/stars/TinaHammar/livewire-auto-routes)](https://github.com/TinaHammar/livewire-auto-routes/stargazers) 9 | [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) 10 | 11 | # Requirements 12 | * Livewire 2 13 | * Laravel 8 14 | * php 8 15 | 16 | # Use Spatie pkg 17 | I recommend that you try [Spatie Laravel Route Attributes](https://github.com/spatie/laravel-route-attributes) before installing this package. 18 | 19 | # Installation 20 | ``` 21 | composer require tanthammar/livewire-auto-routes 22 | ``` 23 | 24 | # Routes in `web.php` takes precedence! 25 | You can use web.php as normal. Routes declared in your Livewire components are registered after the routes in web.php. 26 | 27 | # Usage 28 | * You generate routes via traits or by adding a `route()` method to your Livewire component. 29 | * Your Livewire components can exist in any folder inside the `app` namespace. 30 | * If you don't add any of the traits or the `route()` method, the Livewire component is treated just as a normal component, thus ignored by this package. 31 | 32 | 33 | 34 | ### Guest route Trait 35 | * Applies the `guest` middleware. 36 | * **The property is used to generate both the route name and url.** 37 | 38 | ```php 39 | use Tanthammar\LivewireAutoRoutes\HasGuestRoute; 40 | 41 | class FooComponent extends \Livewire\Component 42 | { 43 | use HasGuestRoute; 44 | 45 | protected string $guestRoute = '/foo/{id}/edit'; //route name becomes 'foo.id.edit' 46 | } 47 | ``` 48 | 49 | ### Auth route Trait 50 | * Applies the `auth` middleware. 51 | * **The property is used to generate both the route name and url.** 52 | 53 | ```php 54 | use Tanthammar\LivewireAutoRoutes\HasAuthRoute; 55 | 56 | class FooComponent extends \Livewire\Component 57 | { 58 | use HasAuthRoute; 59 | 60 | protected string $authRoute = '/foo/{name?}'; //route name becomes 'foo.name' 61 | } 62 | ``` 63 | 64 | # Custom routes 65 | 66 | ### Option 1 67 | Declare the route just like you would in `web.php` 68 | ```php 69 | use Illuminate\Support\Facades\Route; 70 | 71 | class FooComponent extends \Livewire\Component 72 | { 73 | public function route(): \Illuminate\Routing\Route|array 74 | { 75 | return Route::get('foo', static::class) 76 | ->middleware('auth') //default middleware is 'web' 77 | ->name('foo'); 78 | } 79 | } 80 | ``` 81 | 82 | ### Option 2, use the RouteMaker 83 | The RouteMaker can auto-generate the route name from the route definition, but it's optional. 84 | ```php 85 | use Tanthammar\LivewireAutoRoutes\RouteMaker; 86 | 87 | class FooComponent extends \Livewire\Component 88 | { 89 | public function route(): RouteMaker 90 | { 91 | return new RouteMaker( 92 | route: 'users/{id}/edit', //if you omit $name, this route name will become 'users.id.edit' 93 | middleware: ['auth:sanctum', 'verified'], 94 | component: static::class, 95 | name: 'users.edit' //OPTIONAL, else $name will be generated from $route 96 | ); 97 | } 98 | } 99 | ``` 100 | 101 | # Routes are registered in alphabetical order! 102 | Livewire component **FILES** are looped in alphabetical order in the `app namespace`. 103 | One way to control the load order is to group your components in subfolders with suitable names 104 | like `routeGroupA`, `routeGroupB`, where routes in _"routeGroup**A**"_ would be registered before _"routeGroup**B**"_. 105 | 106 | # Example using the Traits 107 | It's recommended to keep a controlled naming structure to avoid route conflicts. Use the `RouteMaker` if you want better naming. 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 |
Directory(asc) = load order$authRoute or $guestRouteGenerated route name
App/Foo/Users/Create.phpusers/createusers.create
App/Foo/Users/CustomStuff.phpusers/custom-stuff/{id}users.custom-stuff.id
App/Foo/Users/Delete.phpusers/delete/{id}users.delete.id
App/Foo/Users/Edit.phpusers/edit/{id}users.edit.id
App/Foo/Users/Index.phpusersusers
App/Foo/Users/Show.phpusers/{id}users.id
131 | 132 | 133 | 134 | ### 💬 Let's connect 135 | Discuss with other tall-form users on the official Livewire Discord channel. 136 | You'll find me in the "partners/tall-forms" channel. 137 | 138 | * [🔗 **Discord**](https://discord.gg/livewire) 139 | * [🔗 **Twitter**](https://twitter.com/TinaHammar) 140 | * [🔗 **Youtube**](https://www.youtube.com/channel/UCRPTsZ2OduwzGq3EdiynY2Q) 141 | * [🔗 **Devdojo**](https://devdojo.com/tinahammar) 142 | 143 | ### Changelog 144 | Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently. 145 | 146 | ### Contributing 147 | Please see [CONTRIBUTING](CONTRIBUTING.md) for details. 148 | 149 | ### Security 150 | If you discover any security-related issues, please open an issue. 151 | 152 | ### License 153 | The MIT License (MIT). Please see [License File](/LICENSE.md) for more information. 154 | -------------------------------------------------------------------------------- /routes/web.php: -------------------------------------------------------------------------------- 1 | group(function () { 7 | $finder = new Finder(); 8 | 9 | // find all files in app 10 | $finder->files() 11 | ->in(app_path())->name('*.php') 12 | ->contains('public function route()') 13 | ->contains('$authRoute') 14 | ->contains('$guestRoute'); 15 | 16 | if ($finder->hasResults()) { 17 | foreach ($finder as $file) { 18 | 19 | $fileNameWithExtension = $file->getRelativePathname(); 20 | 21 | //fix forward slash and remove .php file extension 22 | $component = str_replace( 23 | ['/', '.php'], 24 | ['\\', ''], 25 | $fileNameWithExtension); 26 | 27 | //convert to class 28 | $component = resolve(app()->getNamespace() . $component); 29 | 30 | //add the route if it's a Livewire component 31 | if ($component instanceof \Livewire\Component && method_exists($component, 'route')) $component->route(); 32 | } 33 | } 34 | }); 35 | -------------------------------------------------------------------------------- /src/HasAuthRoute.php: -------------------------------------------------------------------------------- 1 | authRoute, middleware: 'auth', component: static::class); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/HasGuestRoute.php: -------------------------------------------------------------------------------- 1 | guestRoute, middleware: 'guest', component: static::class); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/LivewireAutoRoutesServiceProvider.php: -------------------------------------------------------------------------------- 1 | loadRoutesFrom(__DIR__ . '/../routes/web.php'); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/RouteMaker.php: -------------------------------------------------------------------------------- 1 | makeRoute(); 17 | } 18 | 19 | public function makeRoute(): \Illuminate\Routing\Route|array 20 | { 21 | if(empty($this->name)) { 22 | $routeName = $this->route; 23 | 24 | //remove first forward slash 25 | if (\Str::startsWith($routeName, '/')) $routeName = \Str::replaceFirst('/', '', $routeName); 26 | 27 | //convert to .dot-named route 28 | $routeName = str_replace('/', '.', $routeName); 29 | $routeName = str_replace(['?', '{', '}'], '', $routeName); 30 | 31 | } else { 32 | $routeName = $this->name; 33 | } 34 | 35 | return \Illuminate\Support\Facades\Route::get($this->route, $this->component) 36 | ->middleware($this->middleware) 37 | ->name($routeName); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 |