laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.51k stars 11.02k forks source link

[Proposal] @extendsIfNotAjaxRequest('layouts.master') #1270

Closed crlssn closed 11 years ago

crlssn commented 11 years ago

It would be awesome if there was an option in the blade syntax to not load the master layout if there was an ajax request to the route of the view. The reason why is to avoid multiple views of the same content.

jrahmy commented 11 years ago

If you're using controller layouts, you can override the callMethod function in your BaseController to accomplish this.

protected function callMethod($method, $parameters)
{
    $response = parent::callMethod($method, $parameters);

    if (Request::ajax()) {
        return $response;
    }

    $this->layout->content = $response;
}
taylorotwell commented 11 years ago

Can you elaborate more on the specific use case here?

jrahmy commented 11 years ago

For things like https://github.com/defunkt/jquery-pjax it is usually preferred to disable layouts for ajax requests. It's an easy enough functionality to implement yourself as above, however Rails does have such a feature.

If you do implement this in Laravel (which would be cool), I think it would be best to simply have something like Blade::disableLayouts(); and/or Controller::disableLayout(); so you can control it how you want.

crlssn commented 11 years ago

Because then you could really easy turn any page into a popup modal. Like so: http://paste.laravel.com/rct. And if the user have javascript turned off, the original page will be shown. The code is not tested, but hopefully you'll get the idea.

crynobone commented 11 years ago

When using section, you still need "a layout" to yield it, why not do something like

@extends(Request::ajax() ? 'layout.ajax' : 'layout.main')
Anahkiasen commented 11 years ago

I can see the use case here, not sure about the suggested syntax but I've had to do this quite a few times.

crlssn commented 11 years ago

@Anahkiasen Yeah, the syntax I proposed probably isn't the best one. Maybe something like

return View::make('home.login')
      ->disableLayoutIfAjaxRequest()
      ->with('title', 'Login');
taylorotwell commented 11 years ago

But when extending layouts, as @crynobone pointed out, all the content of the view is normally in section, so rendering it alone wouldn't even look right or be coherent it seems like? For example:

@extends('layout')

@section('content')
    This is the main content!
@endsection

@section('sidebar')
     @parent
     Put this at the bottom of the sidebar
@endsection

What would be rendered in this case?

crlssn commented 11 years ago

Maybe you could choose what section to load instead, like only the content section in your example. At the moment I don't really have a good suggestion for sections that will append to a parent element.

taylorotwell commented 11 years ago

That's getting pretty funky. I would rather just let the app developers handle this how they want.

younes0 commented 10 years ago

Simple solution: create a "blank" layout, with the following content

@yield('content')

And use it for pjax or similar.

tim-peterson commented 9 years ago

Does anyone have a working solution for this? Pjax is really nice (it was created by a Github co-founder and is used extensively on github.com), so it would help alot of people to be able to use it.

I've gotten this to work with the Codeigniter framework and using Laravel when no templating is involved but as soon as I involve Blade templates things start going sour. Been trying for a couple weeks unsuccessfully now. Any thoughts?

@younes0 have you tested your solution? I can't get it to work.

younes0 commented 9 years ago

@tim-peterson give a try to these: