structure changes

This commit is contained in:
Mark Gregory
2026-07-27 14:17:30 +01:00
parent bdb5e7825d
commit df5d6077cb
13 changed files with 468 additions and 277 deletions
@@ -20,6 +20,8 @@ use Modules\Stylist\Services\ThemeSettings;
use Modules\Stylist\Theme\Loader;
use Modules\Stylist\Theme\Stylist;
use Modules\Settings\Services\SettingsRepository;
final class StylistServiceProvider extends ServiceProvider
{
protected string $moduleName = 'Stylist';
@@ -71,16 +73,18 @@ final class StylistServiceProvider extends ServiceProvider
View::composer('stylist-theme-saasland::*', function ($view): void {
$theme = $this->app->make(Loader::class)->find('saasland');
$settings = $this->app->make(ThemeSettings::class)->get($theme);
$siteSettings = $this->app->make(SettingsRepository::class)->site();
$navigation = $this->app->make(FrontendNavigation::class);
$homepage = $this->app->make(FrontendContent::class)->homepage($settings);
$view->with([
'siteTitle' => filled($settings['site_title'] ?? null) ? $settings['site_title'] : config('app.name', 'Saasland'),
'siteDescription' => filled($settings['site_description'] ?? null) ? $settings['site_description'] : 'Modern software for modern companies.',
'logoUrl' => $settings['logo_url'] ?? null,
'facebookUrl' => $settings['facebook_url'] ?? null,
'xUrl' => $settings['x_url'] ?? null,
'linkedinUrl' => $settings['linkedin_url'] ?? null,
'siteSettings' => $siteSettings,
'siteTitle' => $siteSettings['site_name'],
'siteDescription' => $siteSettings['site_description'],
'logoUrl' => $siteSettings['logo_url'] ?: null,
'facebookUrl' => $siteSettings['facebook_url'] ?: null,
'xUrl' => $siteSettings['x_url'] ?: null,
'linkedinUrl' => $siteSettings['linkedin_url'] ?: null,
'primaryNavigation' => $navigation->primary(),
'footerNavigation' => $navigation->footer(),
'themeSettings' => $settings,
+15 -60
View File
@@ -12,33 +12,27 @@ final class FrontendNavigation
/** @return array<int, array<string, mixed>> */
public function primary(): array
{
return $this->forLocations(['primary', 'header', 'main'], $this->fallbackPrimary());
return $this->location('primary', $this->fallbackPrimary());
}
/** @return array<int, array<string, mixed>> */
public function footer(): array
{
return $this->forLocations(['footer'], $this->fallbackFooter());
return $this->location('footer', $this->fallbackPrimary());
}
/** @param array<int, string> $locations
* @param array<int, array<string, mixed>> $fallback
/** @param array<int, array<string, mixed>> $fallback
* @return array<int, array<string, mixed>>
*/
private function forLocations(array $locations, array $fallback): array
public function location(string $location, array $fallback = []): array
{
try {
if (! Schema::hasTable('menus')) {
return $fallback;
}
$menu = Menu::query()
->where('enabled', true)
->whereIn('location', $locations)
->orderByRaw('CASE location '.collect($locations)->map(fn (string $location, int $index) => "WHEN ? THEN {$index}")->implode(' ').' ELSE 999 END', $locations)
->first();
if (! $menu || ! is_array($menu->items) || $menu->items === []) {
$menu = Menu::query()->where('enabled', true)->where('location', $location)->first();
if (! $menu || ! is_array($menu->items)) {
return $fallback;
}
@@ -56,66 +50,27 @@ final class FrontendNavigation
private function normaliseItems(array $items): array
{
return collect($items)
->filter(fn (mixed $item): bool => is_array($item) && ($item['enabled'] ?? true) !== false)
->filter(fn (mixed $item): bool => is_array($item) && filter_var($item['enabled'] ?? true, FILTER_VALIDATE_BOOL))
->map(function (array $item): ?array {
$label = trim((string) ($item['label'] ?? $item['title'] ?? $item['name'] ?? ''));
if ($label === '') {
return null;
}
$url = $this->resolveUrl($item);
if ($url === null) {
return null;
}
$label = trim((string) ($item['label'] ?? ''));
$url = trim((string) ($item['url'] ?? ''));
if ($label === '' || $url === '') return null;
return [
'label' => $label,
'url' => $url,
'target' => ($item['target'] ?? null) === '_blank' ? '_blank' : null,
'children' => $this->normaliseItems((array) ($item['children'] ?? $item['items'] ?? [])),
'target' => ($item['target'] ?? '') === '_blank' ? '_blank' : null,
'children' => $this->normaliseItems((array) ($item['children'] ?? [])),
];
})
->filter()
->values()
->all();
}
/** @param array<string, mixed> $item */
private function resolveUrl(array $item): ?string
{
$routeName = trim((string) ($item['route'] ?? $item['route_name'] ?? ''));
if ($routeName !== '' && Route::has($routeName)) {
return route($routeName, (array) ($item['parameters'] ?? []));
}
$pageSlug = trim((string) ($item['page_slug'] ?? $item['slug'] ?? ''));
if ($pageSlug !== '' && Route::has('pages.public.show')) {
return route('pages.public.show', $pageSlug);
}
$url = trim((string) ($item['url'] ?? $item['href'] ?? ''));
return $url !== '' ? $url : null;
})->filter()->values()->all();
}
/** @return array<int, array<string, mixed>> */
private function fallbackPrimary(): array
{
$items = [['label' => 'Home', 'url' => url('/'), 'target' => null, 'children' => []]];
if (Route::has('blog.public.index')) {
$items[] = ['label' => 'Blog', 'url' => route('blog.public.index'), 'target' => null, 'children' => []];
}
if (Route::has('news.public.index')) {
$items[] = ['label' => 'News', 'url' => route('news.public.index'), 'target' => null, 'children' => []];
}
if (Route::has('blog.public.index')) $items[] = ['label' => 'Blog', 'url' => route('blog.public.index'), 'target' => null, 'children' => []];
if (Route::has('news.public.index')) $items[] = ['label' => 'News', 'url' => route('news.public.index'), 'target' => null, 'children' => []];
return $items;
}
/** @return array<int, array<string, mixed>> */
private function fallbackFooter(): array
{
return $this->fallbackPrimary();
}
}