Question

I'm trying to generate ajax specific responses from my controllers by using the Request::ajax() method, which is working just fine. The only problem is that the way I have it set up right now isn't really a nice looking solution.

My controller:

class HomeController extends BaseController {

protected $layout = 'layouts/main';

public function __construct()
{
    $this->beforeFilter('auth');
}

public function getIndex()
{
    $view = View::make('content.home.index');
    if(Request::ajax()) return $view; //For ajax calls we only want to return the content to be placed inside our container, without the layout
    $this->layout->menu = 'content.menu';
    $this->layout->content = $view;
}

}

So right now, for every method I define within my controllers I need to add the code snippet that checks for an AJAX request and returns a single view if the statement returns true.

This leads to my question that is probably more PHP related than it is to the framework;

Is there a way of executing my AJAX check on every method call, without actually placing it inside the method? Or is there some other solution to keep my code DRY?

Thanks in advance!

PS: This is my first post on stackoverflow, so feel free to correct me if I made any mistakes

Was it helpful?

Solution

Create a new barebone layout named 'layouts/ajax' (or any name you like).

    <?php echo $content ?>

In your Base controller, override this setupLayout() function.

protected function setupLayout()
{
    if ( ! is_null($this->layout))
    {
        $layout = Request::ajax() ? 'layouts/ajax' : $this->layout;
        $this->layout = View::make($layout);            
    }
}

Change your getIndex() function to this.

public function getIndex()
{
    $view = View::make('content.home.index');
    $this->layout->menu = 'content.menu';
    $this->layout->content = $view;
}

Now non-ajax requests will be rendered using layout set in the controller, where as ajax requests will receive whatever set to $this->layout->content.

Note : Controller will neglect the layout setup in setupLayout(), if the called method returns truthy value. So this method will not work for functions like below.

public function getIndex()
{
    return View::make('content.home.index');
}

OTHER TIPS

You could just change the layout property, in the constructor, if it's an ajax request:

public function __construct()
{
    $this->beforeFilter('auth');

    if(Request::ajax()) {
        $this->layout = '';
    }
}

If it doesn't work try setting it to NULL instead.

Why would you return a VIEW via ajax? Are you using it to create a SPA? If so there are better ways. I'm generally against returning HTML via AJAX.

The route I'd go in your position is probably opposite of how you're doing it. Render the view no matter what, if the request is ajax, pass the extra data back and have JS render the data on the page. That's essentially how most Javascript MVC frameworks function.

Sorry if I am totally missing the point here, just going on an assumption of your end goal with the info you provided.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top