Nemanja Kovačević
Nemanja Kovačević

Reputation: 1

Render blade view from URL path

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

Answers (1)

inxilpro
inxilpro

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

Related Questions