8

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.

6
  • maybe try some symlinks if thats what you mean, dunno what the exact goal is Commented Dec 13, 2014 at 11:50
  • my goal is to separate views for admin and for frontend. Commented Dec 13, 2014 at 12:00
  • Then just make "admin" folder in the standard views directory, no? Then you reference the views like admin/mystuff Commented Dec 13, 2014 at 12:01
  • I want to have a separate admin directory for controllers, views, etc. It's cleaner I think than having admin sub directory in each controllers and views. Commented Dec 13, 2014 at 12:04
  • Well of you like it complicated... Commented Dec 13, 2014 at 12:05

4 Answers 4

30

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');
Sign up to request clarification or add additional context in comments.

3 Comments

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).
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 ;)
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 :)
6

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

View::getFinder()
     ->setPaths([
           base_path('themes/frontend/views'), 
           base_path('themes/admin/views')]
     )

Comments

2

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

View::getFinder()->prependLocation(
 resource_path('views') . '/theme'
);

Comments

1

try it like this


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

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.