If I want to add a livewire component at the moment, there isn't a simple way to do this and have those components exist within the modules structure
For example.
I'm using the Data Tables package
I want components for this to exist in [ModuleName]/Http/Livewire/
However because of the way Livewire searches for components this isn't possible
Now I can fix this by registering the components in my Modules/[modulename]/Provider/ServiceProvider
and add something like
Livewire::component('product-datatable', ProductDatatable::class);
but this is a lot of work if I have lots of components to add.
What would be better is if we inspected the [ModuleName]/Http/Livewire/
directory and automatically registered components.
The registration could first just convert the class name from camel case to kebab case
or we could look for a static componentName method
I'm willing to provide a PR for this.
I think it would be easier to add it as a command like this one:
php artisan module:make-livewire [component_name] [module_name]
For me, this issue is also important and this is why I am not using modular approach right now because I like Livewire and the simplicity it brings.
@zcwilt I'm using a custom service provider for livewire components registration. So, no need to register manually every time. It's working for me. You can try this.
Example:
Livewire Component Class - Modules\Contact\Http\Livewire\Frontend\Components\ContactForm
Use this component in the blade file like this - <livewire:contact::frontend.components.contact-form />
Register custom livewire service provider in the core modules service provider -
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->register(RouteServiceProvider::class);
$this->app->register(CustomLivewireServiceProvider::class); // Add this line
}
Custom Livewire Service Provider Class - Modules\Core\Providers\CustomLivewireServiceProvider
<?php
namespace Modules\Core\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Filesystem\Filesystem;
class CustomLivewireServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->loadComponents();
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [];
}
protected function loadComponents()
{
$modules = \Module::toCollection();
$filesystem = new Filesystem();
$modules->map(function ($module) use ($filesystem) {
$modulePath = $module->getPath();
$moduleName = $module->getName();
$path = $modulePath.'/Http/Livewire';
$files = collect( $filesystem->isDirectory($path) ? $filesystem->allFiles($path) : [] );
$files->map(function ($file) use ($moduleName, $path) {
$componentPath = \Str::after($file->getPathname(), $path.'/');
$componentClassPath = strtr( $componentPath , ['/' => '\\', '.php' => '']);
$componentName = $this->getComponentName($componentClassPath, $moduleName);
$componentClassStr = "\\Modules\\{$moduleName}\\Http\\Livewire\\".$componentClassPath;
$componentClass = get_class(new $componentClassStr);
$loadComponent = \Livewire::component($componentName, $componentClass);
});
});
}
protected function getComponentName($componentClassPath, $moduleName = null)
{
$dirs = explode('\\', $componentClassPath);
$componentName = '';
foreach ($dirs as $dir) {
$componentName .= \Str::kebab( lcfirst($dir) ).'.';
}
$moduleNamePrefix = ($moduleName) ? \Str::lower($moduleName).'::' : null;
return \Str::substr($moduleNamePrefix.$componentName, 0, -1);
}
}
m Livewire Service Provider Class - Modules\Core\Providers\CustomLivewireService
Would you be able to PR it? I would love to see this in a future version of Laravel Modules
@FoksVHox Sure, I will provide PR for this very soon.
@FoksVHox I submitted a PR for Livewire Support. #1150
Modules\Channel\Providers\LivewireServiceProvider not found
@zcwilt I'm using a custom service provider for livewire components registration. So, no need to register manually every time. It's working for me. You can try this.
Example:
Livewire Component Class - Modules\Contact\Http\Livewire\Frontend\Components\ContactForm
Use this component in the blade file like this -
<livewire:contact::frontend.components.contact-form />Register custom livewire service provider in the core modules service provider -
/** * Register the service provider. * * @return void */ public function register() { $this->app->register(RouteServiceProvider::class); $this->app->register(CustomLivewireServiceProvider::class); // Add this line }Custom Livewire Service Provider Class - Modules\Core\Providers\CustomLivewireServiceProvider
<?php namespace Modules\Core\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Filesystem\Filesystem; class CustomLivewireServiceProvider extends ServiceProvider { /** * Register the service provider. * * @return void */ public function register() { $this->loadComponents(); } /** * Get the services provided by the provider. * * @return array */ public function provides() { return []; } protected function loadComponents() { $modules = \Module::toCollection(); $filesystem = new Filesystem(); $modules->map(function ($module) use ($filesystem) { $modulePath = $module->getPath(); $moduleName = $module->getName(); $path = $modulePath.'/Http/Livewire'; $files = collect( $filesystem->isDirectory($path) ? $filesystem->allFiles($path) : [] ); $files->map(function ($file) use ($moduleName, $path) { $componentPath = \Str::after($file->getPathname(), $path.'/'); $componentClassPath = strtr( $componentPath , ['/' => '\\', '.php' => '']); $componentName = $this->getComponentName($componentClassPath, $moduleName); $componentClassStr = "\\Modules\\{$moduleName}\\Http\\Livewire\\".$componentClassPath; $componentClass = get_class(new $componentClassStr); $loadComponent = \Livewire::component($componentName, $componentClass); }); }); } protected function getComponentName($componentClassPath, $moduleName = null) { $dirs = explode('\\', $componentClassPath); $componentName = ''; foreach ($dirs as $dir) { $componentName .= \Str::kebab( lcfirst($dir) ).'.'; } $moduleNamePrefix = ($moduleName) ? \Str::lower($moduleName).'::' : null; return \Str::substr($moduleNamePrefix.$componentName, 0, -1); } }
I am getting error class of provider not found
existe esse pacote: https://packagist.org/packages/mhmiton/laravel-modules-livewire
Class '\Modules\Channel\Http\Livewire\C:\xampp\htdocs\boilerplate\Modules\Channel\Http\Livewire\Rule\FormComponent' not found
@aishwaryakumar-hub Did you face this error from this package?
I solved finally
Most helpful comment
I think it would be easier to add it as a command like this one:
php artisan module:make-livewire [component_name] [module_name]For me, this issue is also important and this is why I am not using modular approach right now because I like Livewire and the simplicity it brings.