How to render web and mobile views in Laravel

13,835

Solution 1

One option would be to use a library like Laravel Agent.

https://github.com/jenssegers/Laravel-Agent

if ( Agent::isMobile() ) {
    View::make("file_mobile.blade.php");
} else {
    View::make("file_web.blade.php");
}

Rather than repeat this in each controller method, you may want to abstract this out. A response macro seems like a good option, maybe something like:

Response::macro('ress', function($viewname)
{
    if ( Agent::isMobile() ) {
        return View::make($viewname . "_mobile.blade.php");
    } else {
        return View::make($viewname . "_web.blade.php");
    }
});

So that you can call this in your controller:

return Response::ress('file');

This is all untested code, just to point you in the direction of one possible solution.

Solution 2

jszobody's answer is probably best since you already have the views for each version made, but in the future, I would consider controller layouts.

Basically what you would do is build two layouts, one for mobile and one for non-mobile and set them in the constructor of BaseController. These layouts would contain all the necessary styling, navbar or whatever else all your views should have in common.

public function __construct()
{
    $this->layout = Agent::isMobile() ? 'layouts.mobile' : 'layouts.nonMobile';
}

Both layouts would have a @yields('content') to give it a content section and all your views should only be worried about the content that shows in the layouts.

Then all you have to do is instead of returning a view in your controllers, simply set the content section in the layout.

$this->layout->content = View::make('user.content');`

This is what I do on my personal projects and it usually works out quite well. In the event you want to experiment with a new site layout or need to add a mobile layout or even an admin layout, simply create the layout, modify BaseController::__constructor() to set it when you need to, and you are done.

Share:
13,835
horse
Author by

horse

Updated on August 06, 2022

Comments

  • horse
    horse over 1 year

    I have two blade files for each route, one for web and one for mobile devices. I don't know proper way to handle requests. Is that a proper way:

    At the end of each controller function (For each request)

    If it is mobile (via Jenssegers)
        View::make(file_mobile.blade.php)
    else
        View::make(file_web.blade.php)
    

    What would you suggest?

  • horse
    horse over 9 years
    Thank you. Does making abstraction prevent execution of isMobile function for each request?
  • jszobody
    jszobody over 9 years
    No, isMobile() will still be called on each request since it is part of the macro each controller action calls. The main purpose of this abstraction is just to keep your controller code cleaner, and free from repetitive code.
  • horse
    horse over 9 years
    Isn't the code you inserted deleted when you update laravel framework?
  • user1669496
    user1669496 over 9 years
    It shouldn't. BaseController extends Controller which is an alias for Illuminate\Routing\Controller which would be where any updates happen.
  • horse
    horse over 9 years
    When I enter "composer require jenssegers/agent" or ""composer require jenssegers/agent:dev-master", it gives error. "composer update composer" and "composer self-update" don't solve problem.
  • jszobody
    jszobody over 9 years
    @user2356198 composer require jenssegers/agent just worked for me when I tried it. You may want to go ask at github.com/jenssegers/laravel-agent/issues if you can't get it installed.