Skip to content

Commit 1c9acd0

Browse files
authored
Merge pull request #24 from inertiajs/responsable
Add responsable response
2 parents e694518 + 9d42207 commit 1c9acd0

File tree

10 files changed

+193
-34
lines changed

10 files changed

+193
-34
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/vendor
22
.DS_Store
3+
.phpunit.result.cache
34
composer.lock

composer.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@
2121
"Tests\\": "tests/"
2222
}
2323
},
24-
"require": {
25-
"illuminate/contracts": "^5.8",
26-
"illuminate/support": "^5.8"
27-
},
2824
"require-dev": {
2925
"orchestra/testbench": "~3.0"
3026
},

phpunit.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/7.4/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
forceCoversAnnotation="true"
6+
beStrictAboutCoversAnnotation="true"
7+
beStrictAboutOutputDuringTests="true"
8+
beStrictAboutTodoAnnotatedTests="true"
9+
verbose="true">
10+
<testsuites>
11+
<testsuite name="default">
12+
<directory suffix="Test.php">tests</directory>
13+
</testsuite>
14+
</testsuites>
15+
<filter>
16+
<whitelist processUncoveredFilesFromWhitelist="true">
17+
<directory suffix=".php">src</directory>
18+
</whitelist>
19+
</filter>
20+
</phpunit>

readme.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,21 @@ class EventsController extends Controller
7474
}
7575
~~~
7676

77+
Alternatively, you can use the `with()` method to include component data (props):
78+
79+
~~~php
80+
use Inertia\Inertia;
81+
82+
class EventsController extends Controller
83+
{
84+
public function show(Event $event)
85+
{
86+
return Inertia::render('Event')
87+
->with('event', $event->only('id', 'title', 'start_date', 'description'));
88+
}
89+
}
90+
~~~
91+
7792
## Following redirects
7893

7994
When making a non-GET Inertia request, via `<inertia-link>` or manually, be sure to still respond with a proper Inertia response. For example, if you're creating a new user, have your "store" endpoint return a redirect back to a standard GET endpoint, such as your user index page. Inertia will automatically follow this redirect and update the page accordingly. Here's a simplified example.
@@ -133,17 +148,16 @@ There are situations where you may want to access your prop data in your root Bl
133148
<meta name="twitter:title" content="{{ $page['props']['event']->title }}">
134149
~~~
135150

136-
Sometimes you may even want to provide data that will not be sent to your JavaScript component. You can do this using the `with()` view helper, since `Inertia::render()` returns a `View` instance.
151+
Sometimes you may even want to provide data that will not be sent to your JavaScript component. You can do this using the `withViewData()` method.
137152

138153
~~~php
139-
return Inertia::render('Event', ['event' => $event])
140-
->with(['meta_description' => $event->meta_description]);
154+
return Inertia::render('Event', ['event' => $event])->withViewData(['meta' => $event->meta]);
141155
~~~
142156

143157
You can then access this variable like a regular Blade variable.
144158

145159
~~~blade
146-
<meta name="description" content="{{ $meta_description }}">
160+
<meta name="description" content="{{ $meta }}">
147161
~~~
148162

149163
## Asset versioning

src/Inertia.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,19 @@
55
use Illuminate\Support\Facades\Facade;
66

77
/**
8-
* @method static \Illuminate\Contracts\View\View render($component, $props = [])
9-
* @method static array share($key, $value)
108
* @method static void setRootView($name)
9+
* @method static void share($key, $value)
10+
* @method static array getShared($key = null)
11+
* @method static void version($version)
12+
* @method static int|string getVersion()
13+
* @method static \Inertia\Response render($component, $props = [])
1114
*
12-
* @see \Inertia\Component
15+
* @see \Inertia\ResponseFactory
1316
*/
1417
class Inertia extends Facade
1518
{
1619
protected static function getFacadeAccessor()
1720
{
18-
return Component::class;
21+
return ResponseFactory::class;
1922
}
2023
}

src/Response.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
namespace Inertia;
4+
5+
use Illuminate\Http\JsonResponse;
6+
use Illuminate\Support\Facades\View;
7+
use Illuminate\Contracts\Support\Responsable;
8+
9+
class Response implements Responsable
10+
{
11+
protected $component;
12+
protected $props;
13+
protected $rootView;
14+
protected $sharedProps;
15+
protected $version;
16+
protected $viewData = [];
17+
18+
public function __construct($component, $props, $rootView = 'app', $sharedProps = [], $version = null)
19+
{
20+
$this->component = $component;
21+
$this->props = $props;
22+
$this->rootView = $rootView;
23+
$this->sharedProps = $sharedProps;
24+
$this->version = $version;
25+
}
26+
27+
public function with($key, $value = null)
28+
{
29+
if (is_array($key)) {
30+
$this->props = array_merge($this->props, $key);
31+
} else {
32+
$this->props[$key] = $value;
33+
}
34+
35+
return $this;
36+
}
37+
38+
public function withViewData($key, $value)
39+
{
40+
$this->viewData[$key] = $value;
41+
42+
return $this;
43+
}
44+
45+
public function toResponse($request)
46+
{
47+
$page = [
48+
'component' => $this->component,
49+
'props' => array_merge($this->sharedProps, $this->props),
50+
'url' => $request->getRequestUri(),
51+
'version' => $this->version,
52+
];
53+
54+
if ($request->header('X-Inertia')) {
55+
return new JsonResponse($page, 200, [
56+
'Vary' => 'Accept',
57+
'X-Inertia' => 'true',
58+
]);
59+
}
60+
61+
return View::make($this->rootView, $this->viewData + ['page' => $page]);
62+
}
63+
}

src/Component.php renamed to src/ResponseFactory.php

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,11 @@
44

55
use Illuminate\Support\Arr;
66
use Illuminate\Support\Facades\App;
7-
use Illuminate\Support\Facades\View;
8-
use Illuminate\Support\Facades\Request;
9-
use Illuminate\Support\Facades\Response;
107

11-
class Component
8+
class ResponseFactory
129
{
1310
protected $rootView = 'app';
14-
1511
protected $sharedProps = [];
16-
1712
protected $version = null;
1813

1914
public function setRootView($name)
@@ -23,7 +18,7 @@ public function setRootView($name)
2318

2419
public function share($key, $value)
2520
{
26-
return Arr::set($this->sharedProps, $key, $value);
21+
Arr::set($this->sharedProps, $key, $value);
2722
}
2823

2924
public function getShared($key = null)
@@ -53,20 +48,6 @@ public function render($component, $props = [])
5348
}
5449
});
5550

56-
$page = [
57-
'component' => $component,
58-
'props' => array_merge($this->sharedProps, $props),
59-
'url' => Request::getRequestUri(),
60-
'version' => $this->getVersion(),
61-
];
62-
63-
if (Request::header('X-Inertia')) {
64-
return Response::json($page, 200, [
65-
'Vary' => 'Accept',
66-
'X-Inertia' => 'true',
67-
]);
68-
}
69-
70-
return View::make($this->rootView, ['page' => $page]);
51+
return new Response($component, $props, $this->rootView, $this->sharedProps, $this->getVersion());
7152
}
7253
}

tests/ResponseTest.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
namespace Tests;
4+
5+
use Inertia\Response;
6+
use Illuminate\View\View;
7+
use Illuminate\Http\Request;
8+
use Illuminate\Http\JsonResponse;
9+
10+
class ResponseTest extends TestCase
11+
{
12+
public function test_server_response()
13+
{
14+
$request = Request::create('/user/123', 'GET');
15+
16+
$response = new Response(
17+
'User/Edit',
18+
['user' => ['name' => 'Jonathan']],
19+
'app',
20+
['foo' => 'bar'],
21+
'123'
22+
);
23+
24+
$response = $response->toResponse($request);
25+
$page = $response->getData()['page'];
26+
27+
$this->assertInstanceOf(View::class, $response);
28+
$this->assertSame('User/Edit', $page['component']);
29+
$this->assertSame('Jonathan', $page['props']['user']['name']);
30+
$this->assertSame('bar', $page['props']['foo']);
31+
$this->assertSame('/user/123', $page['url']);
32+
$this->assertSame('123', $page['version']);
33+
$this->assertSame('<div id="app" data-page="{&quot;component&quot;:&quot;User\/Edit&quot;,&quot;props&quot;:{&quot;foo&quot;:&quot;bar&quot;,&quot;user&quot;:{&quot;name&quot;:&quot;Jonathan&quot;}},&quot;url&quot;:&quot;\/user\/123&quot;,&quot;version&quot;:&quot;123&quot;}"></div>'."\n", $response->render());
34+
}
35+
36+
public function test_xhr_response()
37+
{
38+
$request = Request::create('/user/123', 'GET');
39+
$request->headers->add(['X-Inertia' => 'true']);
40+
41+
$response = new Response(
42+
'User/Edit',
43+
['user' => ['name' => 'Jonathan']],
44+
'app',
45+
['foo' => 'bar'],
46+
'123'
47+
);
48+
49+
$response = $response->toResponse($request);
50+
$page = $response->getData();
51+
52+
$this->assertInstanceOf(JsonResponse::class, $response);
53+
$this->assertSame('User/Edit', $page->component);
54+
$this->assertSame('Jonathan', $page->props->user->name);
55+
$this->assertSame('bar', $page->props->foo);
56+
$this->assertSame('/user/123', $page->url);
57+
$this->assertSame('123', $page->version);
58+
}
59+
}

tests/TestCase.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Tests;
4+
5+
use Illuminate\Support\Facades\View;
6+
use Orchestra\Testbench\TestCase as Orchestra;
7+
8+
abstract class TestCase extends Orchestra
9+
{
10+
protected function getPackageProviders($app)
11+
{
12+
return ['Inertia\ServiceProvider'];
13+
}
14+
15+
public function setUp(): void
16+
{
17+
parent::setUp();
18+
19+
View::addLocation(__DIR__.'/views');
20+
}
21+
}

tests/views/app.blade.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@inertia

0 commit comments

Comments
 (0)