Views and Components
A layer keeps its Blade views in resources/views, its translations in lang and its Blade components in src/View/Components. Three methods of LayerServiceProvider register them under the layer's package name, so two layers never collide:
public function boot(): void
{
$this->withViews(__DIR__ . '/../../resources/views');
$this->withTranslations(__DIR__ . '/../../lang');
$this->withComponents('Functional\\Orders\\View\\Components');
}
| Call | Use it as |
|---|---|
withViews() | view('orders::index'), @include('orders::partials.total') |
withTranslations() | __('orders::messages.welcome'), plus the lang/*.json files |
withComponents() | <x-orders::alert /> |
The provider generated by osdd:layer already calls withViews() and withTranslations(). A missing resources/views or lang folder is skipped, so both calls are safe before you add any view.
Views
php artisan osdd:view orders.index --layer=functional/orders
The command creates functional/orders/resources/views/orders/index.blade.php and adds withViews() to the layer provider when it does not call it yet. Render the view with the layer prefix:
return view('orders::orders.index');
view('orders.index'), without the prefix, looks in the root resources/views folder and does not find the layer's view.
Translations
Create the files by hand:
functional/orders/lang/
├── en/messages.php
└── fr.json
return [
'welcome' => 'Welcome to your orders.',
];
{{ __('orders::messages.welcome') }}
The JSON files are loaded without a prefix, like the application's lang/*.json: __('Place order').
Blade components
php artisan osdd:component Alert --layer=functional/orders
The command creates:
src/View/Components/Alert.php, whoserender()returnsview('orders::components.alert');resources/views/components/alert.blade.php;
and adds withViews() and withComponents('Functional\\Orders\\View\\Components') to the layer provider when it does not call them yet. Use the component with the layer prefix:
<x-orders::alert />
| Option | Effect |
|---|---|
--inline | The class renders its view inline: no view file, and no withViews() |
--view | An anonymous component: only the view, and no withComponents() |
--path | Another folder for the view, as with make:component |
--force, --test | As with make:component |
The namespace
Without a second argument, the three methods use the package name of the layer that owns the provider: orders for functional/orders. OSDD finds that layer through the autoload.psr-4 prefixes of the discovered layers: the layer whose prefix covers the provider class owns it.
Pass the second argument to pick another one:
$this->withViews(__DIR__ . '/../../resources/views', 'shop'); // view('shop::index')
$this->withTranslations(__DIR__ . '/../../lang', 'shop'); // __('shop::messages.welcome')
$this->withComponents('Functional\\Orders\\View\\Components', 'shop'); // <x-shop::alert />
A provider that belongs to no discovered layer, or whose layer has no autoload.psr-4 entry for its namespace, has no default: the call throws Lomkit\Osdd\Layers\ProviderLayerNotFoundException at boot. Pass the namespace explicitly.
Two layers with the same package name
functional/orders and technical/orders would both claim orders. The second provider to claim it throws Lomkit\Osdd\Resources\ResourceNamespaceCollisionException at boot, naming both providers. Give one of them another namespace:
$this->withViews(__DIR__ . '/../../resources/views', 'technical-orders');
$this->withTranslations(__DIR__ . '/../../lang', 'technical-orders');
The generators do it for you: when another layer has the same package name, osdd:layer, osdd:view and osdd:component write technical-orders (the full name with -) and warn.
The prefix written in a generated render() follows this order:
- the namespace the application already uses for the layer's
resources/views; vendor-packagewhen another layer shares the package name;- the package name.