How to add package views to master view in Laravel

2019-08-27 15:55发布

问题:

Alright so I'm building multiple packages in my Laravel project, however each package has some administration side with it for example blogs and forums. Now I got my main project, which doesn't do more than supply a pure foundation for all packages.

I got my admin template with it's own main navigation, now I was wondering if there would be a way to dynamically load in extensions of this menu from the packages? Here's the structure of the whole thing:

Resources 
     - views
        - cp
           - homer //Name of the template
             - master.blade.php
             - components
                 - nav.blade.php

Now inside my package I would have the following structure

views
    - cp
        - components
            - nav.blade.php

What would be the best step to merge all packages with the same structure to merge all nav.blade.php's together?

回答1:

You can see how Laravel does this with email and other notification views by publishing the vendor files. Here's the relevant documentation: publishing views.

To register your package's views with Laravel, you need to tell Laravel where the views are located. You may do this using the service provider's loadViewsFrom method. The loadViewsFrom method accepts two arguments: the path to your view templates and your package's name. For example, if your package's name is courier, you would add the following to your service provider's boot method:

public function boot() { 
    $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier'); 
}

Package views are referenced using the package::view syntax convention. So, once your view path is registered in a service provider, you may load the admin view from the courier package like so:

Route::get('admin', function () { 
   return view('courier::admin'); 
});


回答2:

As a result I ended up creating my own service as follow:

namespace App\Services;

class ComposerService {

    public function getLoadedPackages()
    {
        $folders = scandir(base_path('packages/author'));

        unset($folders[0]);
        unset($folders[1]);
        unset($folders[2]);

        return $folders;
    } 
}

This will read out the correct folder I create my own packages is

After that I updated the AppServiceProvider

in the boot function I did the following

 /** @var \App\Services\ComposerService $compiler */
    $compiler = new ComposerService();

    $packages = $compiler->getLoadedPackages();

    $compiled = '';

    foreach($packages as $package)
    {
        $compiled .= view('prefix-'.$package.'::cp.components.nav')->render();
    }

    View::share('main_nav', $compiled);

Now I can access main_nav in my blade and use it like

{!! $main_nav !!}

It now prints out all my nav views that I have for each package.