Reputation: 1
I've an unusual and interesting problem that I am trying to solve.
We had to put some of our blade views to S3 storage and render them from S3 url with passed variables.
For example:
view('page.user.show', ['user' => User::first()])->render();
Now, since we have our page.user.show blade file stored in S3 storage on the path "/views/pages/user/show.blade.php"
We somehow need to make Laravel get that view from s3 URL path instead from resource_path
So we need something like this:
view('s3url.com/views/pages/user/show.blade.php', ['user' => User::first()])->render();
Is there any way we can do this in Laravel ? Or, at least read content of blade file from S3 path and render that string content with variables?
Upvotes: 0
Views: 578
Reputation: 20592
To achieve something like this, you'll need to implement a custom version of the Laravel Illuminate\View\ViewFinderInterface
. Your best bet is to create a new view finder that can load blade templates from S3 and move them to the local filesystem temporarily.
You can probably just extend the FileViewFinder
class, and add some custom logic to the find()
method. In there, try something like:
if (Str::startsWith($name, 's3::')) {
// This gets a temp file that PHP will clean up for you
$name = stream_get_meta_data(tmpfile())['uri'];
// Download the Blade template from S3 and store it temporarily
file_put_contents($name, Storage::disk('s3')->get(Str::after($name, 's3::')));
// Return the path
return $name;
}
Then you'll need to swap in your new finder using View::setFinder
.
The major downside of this approach is that you'll need to download views from S3 every time you render them. You probably want to at least add some caching to the system so that you're not hitting S3 every time a page loads.
Upvotes: 0