1+ # Laravel Inertia Data Providers
12
2- [ <img src =" https://github-ads.s3.eu-central-1.amazonaws.com/support-ukraine.svg?t=1 " />] ( https://supportukrainenow.org )
3+ [ ![ Latest Version on Packagist] ( https://img.shields.io/packagist/v/webfox/laravel-inertia-dataproviders.svg?style=flat-square )] ( https://packagist.org/packages/webfox/laravel-inertia-dataproviders )
4+ [ ![ GitHub Tests Action Status] ( https://img.shields.io/github/workflow/status/webfox/laravel-inertia-dataproviders/run-tests?label=tests )] ( https://github.com/webfox/laravel-inertia-dataproviders/actions?query=workflow%3Arun-tests+branch%3Amain )
5+ [ ![ GitHub Code Style Action Status] ( https://img.shields.io/github/workflow/status/webfox/laravel-inertia-dataproviders/Check%20&%20fix%20styling?label=code%20style )] ( https://github.com/webfox/laravel-inertia-dataproviders/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain )
6+ [ ![ Total Downloads] ( https://img.shields.io/packagist/dt/webfox/laravel-inertia-dataproviders.svg?style=flat-square )] ( https://packagist.org/packages/webfox/laravel-inertia-dataproviders )
37
4- # : package_description
5-
6- [ ![ Latest Version on Packagist] ( https://img.shields.io/packagist/v/:vendor_slug/:package_slug.svg?style=flat-square )] ( https://packagist.org/packages/:vendor_slug/:package_slug )
7- [ ![ GitHub Tests Action Status] ( https://img.shields.io/github/workflow/status/:vendor_slug/:package_slug/run-tests?label=tests )] ( https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3Arun-tests+branch%3Amain )
8- [ ![ GitHub Code Style Action Status] ( https://img.shields.io/github/workflow/status/:vendor_slug/:package_slug/Check%20&%20fix%20styling?label=code%20style )] ( https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain )
9- [ ![ Total Downloads] ( https://img.shields.io/packagist/dt/:vendor_slug/:package_slug.svg?style=flat-square )] ( https://packagist.org/packages/:vendor_slug/:package_slug )
10- <!-- delete-->
11- ---
12- This repo can be used to scaffold a Laravel package. Follow these steps to get started:
13-
14- 1 . Press the "Use template" button at the top of this repo to create a new repo with the contents of this skeleton.
15- 2 . Run "php ./configure.php" to run a script that will replace all placeholders throughout all the files.
16- 3 . Have fun creating your package.
17- 4 . If you need help creating a package, consider picking up our <a href =" https://laravelpackage.training " >Laravel Package Training</a > video course.
18- ---
19- <!-- /delete-->
20- This is where your description should go. Limit it to a paragraph or two. Consider adding a small example.
21-
22- ## Support us
23-
24- [ <img src =" https://github-ads.s3.eu-central-1.amazonaws.com/:package_name.jpg?t=1 " width =" 419px " />] ( https://spatie.be/github-ad-click/:package_name )
25-
26- 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 ) .
27-
28- 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 ) .
8+ Data providers encapsulate logic for Inertia views, keep your controllers clean and simple.
299
3010## Installation
3111
32- You can install the package via composer:
12+ We assume you've already got Inertia installed, so you can just install this package via composer:
3313
3414``` bash
35- composer require :vendor_slug/:package_slug
15+ composer require webfox/laravel-inertia-dataproviders
3616```
3717
38- You can publish and run the migrations with:
18+ ## Usage
3919
40- ``` bash
41- php artisan vendor:publish --tag=" :package_slug-migrations"
42- php artisan migrate
20+ ### Using a Data Provider
21+ Data providers take advantage of the fact that ` Inertia::render ` can accept ` Arrayable ` s as well as standard arrays and so are used
22+ instead a standard array in the ` Inertia::render ` method. They can also be used as discrete attributes in the data array.
23+
24+ ``` php
25+ use App\Models\Demo;
26+ use App\DataProviders\DemoDataProvider;
27+
28+ class DemoController extends Controller
29+ {
30+ public function show(Demo $demo)
31+ {
32+ return Inertia::render('DemoPage', new DemoDataProvider($demo));
33+ }
34+
35+ public function edit(Demo $demo)
36+ {
37+ return Inertia::render('DemoPage', [
38+ 'some' => 'data',
39+ 'more' => 'data',
40+ 'demo' => new DemoDataProvider($demo),
41+ ]);
42+ }
43+ }
4344```
4445
45- You can publish the config file with:
46+ ### What Does a Data Provider Look Like?
4647
47- ``` bash
48- php artisan vendor:publish --tag=" :package_slug-config"
49- ```
48+ Data providers can live anywhere, but we'll use ` App/Http/DataProviders ` for this example.
5049
51- This is the contents of the published config file:
50+ The simplest data provider is just a class that extends ` DataProvider ` , any public methods or properties will be available to the page as data.
51+ A ** fully featured** data provider might look like this:
5252
5353``` php
54- return [
55- ];
54+ <?php
55+ declare(strict_types=1);
56+
57+ namespace App\Http\DataProviders;
58+
59+ use Inertia\LazyProp;
60+ use App\Services\InjectedDependency;
61+ use Webfox\InertiaDataProviders\DataProvider;
62+
63+ class DemoDataProvider extends DataProvider
64+ {
65+
66+ public function __construct(
67+ /*
68+ * All public properties are automatically available in the page
69+ * This would be available to the page as `demo`
70+ */
71+ public Demo $demo;
72+ )
73+ {
74+ /*
75+ * Data providers have a `staticData` property, which you can use to add any data that doesn't warrant a full
76+ * property or separate method
77+ */
78+ $this->staticData = [
79+ /*
80+ * This will be available to the page as `title`
81+ */
82+ 'title' => $this->calculateTitle($demo),
83+ ];
84+ }
85+
86+ /*
87+ * All public methods are automatically evaluated as data and provided to the page.
88+ * ALWAYS included on first visit, OPTIONALLY included on partial reloads, ALWAYS evaluated
89+ * This would be available to the page as `someData`.
90+ * Additionally these methods are resolved through Laravel's service container, so any parameters will be automatically resolved.
91+ */
92+ public function someData(InjectedDependency $example): array
93+ {
94+ return [
95+ 'some' => $example->doThingWith('some'),
96+ 'more' => 'data',
97+ ];
98+ }
99+
100+ /*
101+ * If a method returns a `Closure` it will be evaluated as a lazy property.
102+ * ALWAYS included on first visit, OPTIONALLY included on partial reloads, ONLY evaluated when needed
103+ * Additionally the callback methods are resolved through Laravel's service container, so any parameters will be automatically resolved.
104+ * @see https://inertiajs.com/partial-reloads#lazy-data-evaluation
105+ */
106+ public function quickLazyExample(): Closure
107+ {
108+ return function(InjectedDependency $example): string {
109+ return $example->formatName($this->demo->user->name);
110+ };
111+ }
112+
113+ /*
114+ * If a method is typed to return a LazyProp, it will only be evaluated when requested following inertia's rules for lazy data evaluation
115+ * NEVER included on first visit, OPTIONALLY included on partial reloads, ONLY evaluated when needed
116+ * Additionally the lazy callback methods are resolved through Laravel's service container, so any parameters will be automatically resolved.
117+ * @see https://inertiajs.com/partial-reloads#lazy-data-evaluation
118+ */
119+ public function lazyExample(): LazyProp
120+ {
121+ return Inertia::lazy(
122+ fn (InjectedDependency $example) => $example->aHeavyCalculation($this->demo)
123+ );
124+ }
125+
126+ /*
127+ * `protected` and `private` methods are not available to the page
128+ */
129+ protected function calculateTitle(Demo $demo): string
130+ {
131+ return $demo->name . ' Demo';
132+ }
133+
134+ }
56135```
57136
58- Optionally, you can publish the views using
137+ ### Using Multiple Data Providers
138+ Sometimes you might find yourself wanting to return multiple DataProviders ` DataProvider::collection ` is the method for you.
139+ Each DataProvider in the collection will be evaluated and merged into the page's data, later values from DataProviders will override earlier DataProviders.
59140
60- ``` bash
61- php artisan vendor:publish --tag=" :package_slug-views"
141+ ``` php
142+ use App\Models\Demo;
143+ use App\DataProviders\TabDataProvider;
144+ use App\DataProviders\DemoDataProvider;
145+
146+ class DemoController extends Controller
147+ {
148+ public function show(Demo $demo)
149+ {
150+ return Inertia::render('DemoPage', DataProvider::collection(
151+ new TabDataProvider(current: 'demo'),
152+ new DemoDataProvider($demo),
153+ ));
154+ }
155+ }
62156```
63157
64- ## Usage
65-
158+ You can also conditionally include DataProviders in the collection:
66159``` php
67- $variable = new VendorName\Skeleton();
68- echo $variable->echoPhrase('Hello, VendorName!');
160+ use App\Models\Demo;
161+ use App\DataProviders\TabDataProvider;
162+ use App\DataProviders\DemoDataProvider;
163+ use App\DataProviders\EditDemoDataProvider;
164+ use App\DataProviders\CreateVenueDataProvider;
165+
166+ class DemoController extends Controller
167+ {
168+ public function show(Demo $demo)
169+ {
170+ return Inertia::render('DemoPage', DataProvider::collection(
171+ new TabDataProvider(current: 'demo'),
172+ new DemoDataProvider($demo),
173+ )->when($demo->has_venue, function (DataProviderCollection $collection) use($demo) {
174+ $collection->push(new CreateVenueDataProvider($demo));
175+ })
176+ ->unless($demo->locked, function (DataProviderCollection $collection) use($demo) {
177+ $collection->push(new EditDemoDataProvider($demo));
178+ }));
179+ }
180+ }
69181```
70182
71- ## Testing
72-
73- ``` bash
74- composer test
183+ Or you can use the ` DataProviderCollection::add ` method to add a DataProvider to the collection later:
184+ You can also conditionally include DataProviders in the collection:
185+ ``` php
186+ use App\Models\Demo;
187+ use App\DataProviders\TabDataProvider;
188+ use App\DataProviders\DemoDataProvider;
189+ use App\DataProviders\EditDemoDataProvider;
190+ use App\DataProviders\CreateVenueDataProvider;
191+
192+ class DemoController extends Controller
193+ {
194+ public function show(Demo $demo)
195+ {
196+ $pageData = DataProvider::collection(
197+ new TabDataProvider(current: 'demo'),
198+ new DemoDataProvider($demo),
199+ );
200+
201+ if($demo->has_venue) {
202+ $pageData->add(new CreateVenueDataProvider($demo));
203+ }
204+
205+ return Inertia::render('DemoPage', $pageData);
206+ }
207+ }
75208```
76209
77210## Changelog
@@ -80,16 +213,7 @@ Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed re
80213
81214## Contributing
82215
83- Please see [ CONTRIBUTING] ( https://github.com/spatie/.github/blob/main/CONTRIBUTING.md ) for details.
84-
85- ## Security Vulnerabilities
86-
87- Please review [ our security policy] ( ../../security/policy ) on how to report security vulnerabilities.
88-
89- ## Credits
90-
91- - [ : author_name ] ( https://github.com/:author_username )
92- - [ All Contributors] ( ../../contributors )
216+ We welcome all contributors to the project.
93217
94218## License
95219
0 commit comments