-
Notifications
You must be signed in to change notification settings - Fork 0
Layouts
A site is rarely one shell. Marketing pages want a navbar and a footer, documentation wants a sidebar, a landing page often wants neither. The blocks are the same either way, so the shell is a per-page choice rather than a different set of blocks.
A layout is a Blade view you write, registered with a key and a label. The client picks one from a dropdown on the page settings screen.
Where you register blocks:
use Safi\Atelier\AtelierPlugin;
use Safi\Atelier\Blocks\DefaultBlocks;
->plugins([
AtelierPlugin::make()
->blocks(DefaultBlocks::all())
->layouts([
'site' => [
'label' => 'Navbar and footer',
'view' => 'layouts.site',
'description' => 'The marketing shell. Full-width sections.',
],
'docs' => [
'label' => 'Sidebar',
'view' => 'layouts.docs',
],
'bare' => 'layouts.bare',
]),
])The long form takes label, view and an optional description. The short form is just
the view name, and the label comes from the key, so 'bare' => 'layouts.bare' shows as
Bare.
A layout is a map rather than a class. Blocks earn a class because they carry a schema, an icon, a category and translatable keys; a layout is a key, a label and a view, and a class holding three strings is ceremony.
Page settings, under the title: a Layout dropdown. It hides itself entirely when the app has registered no layouts, because a question with one answer is not a question.
Empty means Default, the site-wide atelier.layout. Registering layouts does not force
every page to pick one.
The choice is page-level, not per locale. A layout is structure, and both locales share one structure by design, the same reason Arabic cannot have a different section order from English.
A layout receives:
| Variable | What it is |
|---|---|
$blocks |
The rendered HTML of every section. Echo it unescaped. |
$page |
The page model, for a title, a nav highlight, anything else |
$locale |
Current locale code |
$title |
Meta title, falling back to the page title |
$preview |
True when the editor's iframe is rendering it |
A documentation shell with a sidebar:
@php
$locales = config('atelier.locales', []);
$dir = $locales[$locale]['dir'] ?? 'ltr';
// Don't assume Atelier's controllers are the only caller.
$page = $page ?? null;
$nav = \Safi\Atelier\Models\Page::query()
->where('status', 'published')
->orderBy('title')
->get();
@endphp
<!DOCTYPE html>
<html lang="{{ $locale }}" dir="{{ $dir }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
@include('atelier::partials.meta')
@vite(['resources/css/app.css'])
@include('atelier::partials.tokens')
</head>
<body class="bg-white text-neutral-900 antialiased">
<div class="mx-auto flex max-w-7xl gap-10 px-6 py-10">
<aside class="hidden w-56 shrink-0 lg:block">
<nav class="space-y-1 border-s border-neutral-200 ps-4">
@foreach ($nav as $item)
@if ($url = $item->url($locale))
<a href="{{ $url }}"
@class([
'block py-1 text-sm',
'font-medium' => $page && $item->is($page),
'text-neutral-500 hover:text-neutral-900' => ! ($page && $item->is($page)),
])>{{ $item->title }}</a>
@endif
@endforeach
</nav>
</aside>
<main class="min-w-0 flex-1" data-atelier-canvas>
{!! $blocks !!}
</main>
</div>
</body>
</html>There is a working copy of this in example/resources/views/layouts/docs.blade.php.
-
Include both partials.
atelier::partials.metain the head carries the title, description, canonical, hreflang, Open Graph and thenoindexon previews.atelier::partials.tokensgoes after your stylesheet and defines everyvar(--atelier-*). Leave either out and nothing errors: the page renders with no head, or the section controls and the Arabic font silently stop working. See Using your own layout. -
Put
data-atelier-canvason the element wrapping{!! $blocks !!}. The editor swaps the contents of that element on every preview refresh. Without it the preview reloads the whole iframe, losing scroll position, or stops updating. -
Guard
$page. Write$page = $page ?? nullif you use it. A layout rendered by anything other than Atelier's controllers will not have it. -
Tailwind has to scan your layout. Layouts live in your app, so it already does. It is
the package's views that need the
@sourceline from Installation.
Nothing visible. Delete a layout from the panel provider and pages still naming it fall back to the site-wide default. A page keeps its layout key after the code that defined it is gone, and a 500 on every public page is a bad way to find that out.
The editor's preview renders through the same layout the public page will use, resolved by the same method. A preview rendered through a different shell is a preview that lies, which is the whole reason the preview exists.
Building
Running a site
Reference