7

I have a directory structure for laravel app like this:

app/
   admin/
      controllers/
      views/ -> for admin views
   ...
   views/ -> for frontend views

How can I set the view path for controllers in admin? I don't want to use View::addLocation or View::addNamespace because I might have the same view file name for admin and frontend, and don't want to add a namespace for every View::make('namespace::view.file').

I see in http://laravel.com/api/4.2/Illuminate/View/View.html there is a setPath method, but how do I call it? View::setPath raised undefined method error.

xdim222
  • 453
  • 1
  • 5
  • 10

4 Answers4

27

You have two ways to accomplish your goal. First, let's have a look at app/config/view.php. That's where the path(s) for view loading are defined.

This is the default:

'paths' => array(__DIR__.'/../views'),

Method 1: Load both directories

You can easily add the admin directory to the array

'paths' => array(
    __DIR__.'/../views',
    __DIR__.'/../admin/views
),

Now the big disadvantage of this: view names have to be unique. Otherwise the view in the path specified first will be taken.
Since you don't want to use a view namespace I suppose you don't want a syntax like admin.viewname either. You'll probably like method 2 more ;)

Method 2: Change the view page at runtime

Every Laravel config can be changed at runtime using the Config::set method.

Config::set('view.paths', array(__DIR__.'/../admin/views'));

Apparently setting the config won't change anything because it is loaded when the application bootstraps and ignored afterwards.

To change the path at runtime you have to create a new instance of the FileViewFinder.
Here's how that looks like:

$finder = new \Illuminate\View\FileViewFinder(app()['files'], array(app_path().'/admin/views'));
View::setFinder($finder);

Method 3: Use addLocation but without default path

You could also remove the default path in app/config/view.php

'paths' => array(),

And then use View::addLocation in any case (frontend and admin)

View::addLocation(app_path().'/views');
View::addLocation(app_path().'/admin/views');
lukasgeiter
  • 147,337
  • 26
  • 332
  • 270
  • Thanks for your reply. I think method 1 is the same as `View::addLocation`. I tried method 2 but it doesn't seem to work, I put `Config::set` in the controller `__construct`, but laravel seems to ignore that (means laravel still load the view file from 'original' path). – xdim222 Dec 14 '14 at 03:18
  • Sorry... that happens when you don't test the things you post on SO. Take a look at the updated answer. This time I even tested it ;) – lukasgeiter Dec 14 '14 at 13:56
  • Right now I'm going to use method 3, but I think I'll consider to use method 2 later, because method 3 might raise another problem when I have another view directory (although it's less possible) in one module (frontend/admin), anyway method 2 looks more 'right way' to do this IMHO :) – xdim222 Dec 14 '14 at 15:51
5

In the latest version 6 i am doing it this ways:

View::getFinder()
     ->setPaths([
           base_path('themes/frontend/views'), 
           base_path('themes/admin/views')]
     )
Purvesh
  • 628
  • 7
  • 12
2

In Laravel 5.5, other solutions did not work. In boot method of a service provider

View::getFinder()->prependLocation(
 resource_path('views') . '/theme'
);
cthiele
  • 23
  • 4
0

try it like this


View::addNamespace('admin', app_path() . '/admin/views');

Route::group(['prefix' => 'admin'], function() {
  Route::get('/', function() {
    return view('admin::index');
  });
});