├── .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 | [](//packagist.org/packages/tanthammar/livewire-auto-routes)
5 | [](//packagist.org/packages/tanthammar/livewire-auto-routes)
6 | [](//packagist.org/packages/tanthammar/livewire-auto-routes)
7 | [](https://github.com/TinaHammar/livewire-auto-routes/issues)
8 | [](https://github.com/TinaHammar/livewire-auto-routes/stargazers)
9 | [](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 | Directory(asc) = load order | $authRoute or $guestRoute | Generated route name |
111 |
112 |
113 | App/Foo/Users/Create.php | users/create | users.create |
114 |
115 |
116 | App/Foo/Users/CustomStuff.php | users/custom-stuff/{id} | users.custom-stuff.id |
117 |
118 |
119 | App/Foo/Users/Delete.php | users/delete/{id} | users.delete.id |
120 |
121 |
122 | App/Foo/Users/Edit.php | users/edit/{id} | users.edit.id |
123 |
124 |
125 | App/Foo/Users/Index.php | users | users |
126 |
127 |
128 | App/Foo/Users/Show.php | users/{id} | users.id |
129 |
130 |
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 |