Search code examples
laravellaravel-5.3laravel-bladelaravel-views

Having a dynamic View folder path during runtime in laravel 5.3


I'm trying to build a saas application (saas here means software as a service) in laravel 5.3. I've build few service provider which collects the domain name, the theme being used and databases of those particular website. Now I'm trying to implement the pages with view structure through service provider. Now for example I'm having two different themes for two different domains. I'm having the set of HTML code in views in different folders, something like this:

View
----| Theme One
--------| Navbar
--------| Sliders
--------| Tabs
--------| Parallax
--------| Iconbox
--------| template.blade.php
----| Theme Two
--------| Navbar
--------| Sliders
--------| Tabs
--------| Parallax
--------| Iconbox
--------| template.blade.php

Now I want to define folder structure dynamically for these domains so that it should show the modules of their respective theme. Like suppose if I want to include sub-view of Navbar I just have to write

@include('Navbar')

and it should access the respective theme Navbar folder or sub-view. I thought of making a service provider and trying to set via config the path something like this:

public function boot()
{
    $this->webView = $this->setPath();
    $this->app->singleton('webView', function()
    {
        return $this->webView;
    });
}

public function setPath()
{
    $themename = App::make('themename')
    if($themename)
    {
        $setpath = "..Path\Views\" . $themename;
        Config::set('view.paths', $setpath);
        return null;
    }
    else
    {
        return "Not found";
    }
}

But I guess when the application bootstraps it will ignore the configuration, I know there must be a better way in implementing this. Please guide me.


Solution

  • First create a ViewServiceProvider in App\Providers like this or copy Illuminate\View\ViewServiceProvider in app/Providers & change like this

    <?php
    
    namespace App\Providers;
    
    use Illuminate\View\FileViewFinder;
    use Illuminate\View\ViewServiceProvider as ConcreteViewServiceProvider;
    
    class ViewServiceProvider extends ConcreteViewServiceProvider
    {
        /**
         * Register the view finder implementation.
         *
         * @return void
         */
        public function registerViewFinder()
        {
            $this->app->bind('view.finder', function ($app) {
                $paths = $app['config']['view.paths'];
    
                //change your paths here
                foreach ($paths as &$path)
                {
                    $path .= time();//change with your requirement here I am adding time value with all path
                }
    
                return new FileViewFinder($app['files'], $paths);
            });
        }
    }
    

    then replace your Illuminate\View\ViewServiceProvider::class, with App\Providers\ViewServiceProvider::class, in config/app.php. This will do the trick.