-
Notifications
You must be signed in to change notification settings - Fork 11.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[9.x] Adds template fragments to Blade #44774
Conversation
Whilst this concept is interesting and most likely useful for some, I imagine that 90% of use cases would hit performance problems since the entire view needs to be rendered with all of the correct data fully before the fragment can be retrieved / returned from the controller. At that point the logical solution would be abstracting out the view into a partial and using it in both the initially rendered template and separately to render and return via a controller, right? |
Currently the only alternative is to send the entire view to the front anyway (also consuming more bandwidth), then the front library would interpret what portion of the DOM to replace, of course only if it has this feature, some libraries expect a specific element as the root of the tree. The other alternative is to split the file into components (which defeats the purpose of this feature), and then return them via To me it definitely feels like there should be a way to return just a fragment of a view. I think the question is whether this should be packaged or core. |
First of all, this is really cool. There's an issue in the Turbo Laravel repo to investigate something like this. We do have a possible solution of just not rendering the layout when it's a Turbo Frame request, but I do like the idea of having something like this in code. To @ryangjchandler's point, do you think we could find a way to only render the fragment itself, but not the whole view? That would be dope because it could potentially avoid evaluating other parts of the view that are not necessary (let's say other parts are making database calls, for instance). Although that would be wonderful, I still think this is useful because it may reduce the amount of data sent over the wire and it reduces the surface of the response, which is really cool especially while in development mode since we can view the source of the response more clearly (without the surroundings). For Turbo Laravel, I think the main middleware could implement something like this: <?php
namespace Tonysm\TurboLaravel\Http\Middleware;
use Illuminate\Contracts\View\View;
class TurboMiddleware
{
public function handle($request, $next)
{
$response = $next($request);
// Do other things the middleware does...
if ($frame = $request->header('Turbo-Frame') && $response instanceof View) {
return $view->segment($frame);
}
return $response;
}
} This assumes each Turbo Frame declares its own fragment. I dig it. |
Hey @tonysm. Nice package! We've been using it for a while now. 💯 Personally I don't think a Fragment should be rendered without a context, because then it'd just fall under the component-ish category, which is not. I think of a Fragment as a way to extract a portion of a view. Your example reminds me of the middleware Spatie created for Pjax, where basically the render of the view was parsed, and then an element of the DOM extracted. I view the result of that process as a Fragment. Actually, I was porting that middleware to Turbo (frames) when I realized this implementation of Fragments might be better. Regardless of the implementation I do believe Fragments are an imporant tool for us who use html over-the-wire. |
we need this for unpoly 👍👍 |
Thanks |
This is funny! I've just released a helper package for HTMX that handles Blade fragments as well https://github.com/mauricius/laravel-htmx. The implementation relies on a regex expression so it's likely gonna break in some weird cases, but it allows to extract a portion of a view without rendering the entire file. |
IMHO, fragments should work without passing whole variables used by the view. It should be sufficient to just pass the variables to be used by the fragment. So, |
What's problem with just moving fragment to separate blade file and include it in main blade file and in response? public function updateStatus()
{
return view('users.profile.actions', $data);
}
|
@decadence it's perfectly fine to extract fragments in separate files, but sometimes it's more useful to have them at the level of the parent template. This article explains the issue better than I can do. |
Docs for PR: laravel/framework#44774
* [9.x] Add Fragment Helpers Docs for PR: laravel/framework#44774 * formatting --------- Co-authored-by: Taylor Otwell <taylor@laravel.com>
* [9.x] Add Fragment Helpers Docs for PR: laravel/framework#44774 * formatting --------- Co-authored-by: Taylor Otwell <taylor@laravel.com>
Hello everyone! This PR adds fragments to Blade, suggested in #44468.
Working with frontend frameworks that use the html over-the-wire concept such as Turbo, Unpoly, Htmx or Pjax, sometimes when handling a request we have to return just a fragment of a view to replace a portion of the DOM.
Adding this feature will allow developers to return said fragment from a controller without having to create a component and split the view in several files.
As mentioned in the original discussion there are several implementations of this feature in other backend template engines, here's a detailed list.
Although this can be extracted to a package I think it would be a nice addition to the framework.
Usage