# Templates — Création et conventions

## Concept

Un template définit la **structure** d'une page : quelles zones existent,
quel layout Vue est utilisé, et quelle disposition s'affiche.

```
Template "Pleine largeur"
  └── Zones : ["content"]
  └── Layout Vue : FullWidthLayout.vue

Template "Avec sidebar"
  └── Zones : ["content", "sidebar"]
  └── Layout Vue : SidebarLayout.vue

Template "Landing page"
  └── Zones : ["hero", "content", "cta"]
  └── Layout Vue : LandingLayout.vue
```

---

## Modèle de données

```php
// Template
[
  'id'        => 1,
  'name'      => 'Pleine largeur',
  'slug'      => 'full-width',
  'thumbnail' => '/storage/templates/full-width.png',
  'zones'     => ["content"],               // JSON array
]
```

---

## Templates disponibles (définis au démarrage)

| Slug | Nom | Zones | Layout Vue |
|---|---|---|---|
| `full-width` | Pleine largeur | `content` | `FullWidthLayout.vue` |
| `sidebar` | Avec sidebar | `content`, `sidebar` | `SidebarLayout.vue` |
| `landing` | Landing page | `hero`, `content`, `cta` | `LandingLayout.vue` |
| `home` | Accueil | `hero`, `content` | `HomeLayout.vue` |

---

## Résolution du template (Laravel)

```php
// app/Services/TemplateService.php
public function resolveComponent(Page $page): string
{
    return match($page->template->slug) {
        'full-width' => 'Templates/FullWidth',
        'sidebar'    => 'Templates/Sidebar',
        'landing'    => 'Templates/Landing',
        'home'       => 'Templates/Home',
        default      => 'Templates/FullWidth',
    };
}
```

```php
// app/Http/Controllers/Front/PageController.php
public function show(string $slug)
{
    $page = Page::with(['blocks', 'template'])->whereSlug($slug)->firstOrFail();

    return Inertia::render(
        $this->templateService->resolveComponent($page),
        [
            'page'    => $page,
            'blocks'  => $page->blocks->groupBy('zone'),
            'menus'   => MenuService::all(),
            'settings'=> SettingsService::shared(),
        ]
    );
}
```

---

## Structure d'un Layout Vue (front-office)

```vue
<!-- frontoffice/layouts/FullWidthLayout.vue -->
<template>
  <div class="layout-full-width">
    <NavMenu :items="menus['header']" />

    <main>
      <slot name="content" />
    </main>

    <footer>
      <NavMenu :items="menus['footer']" />
    </footer>
  </div>
</template>

<script setup>
import { usePage } from '@inertiajs/vue3'
import NavMenu from '../components/NavMenu.vue'

const { menus } = usePage().props
</script>
```

---

## DynamicPage — Rendu des blocs dans les zones

```vue
<!-- frontoffice/pages/DynamicPage.vue -->
<!-- Utilisé par TOUS les templates via Inertia::render() -->
<template>
  <component :is="currentLayout">
    <template v-for="zone in template.zones" :key="zone" #[zone]>
      <component
        v-for="block in blocks[zone] ?? []"
        :key="block.id"
        :is="getRender(block.type)"
        v-bind="block.props"
      />
    </template>
  </component>
</template>

<script setup>
import { computed } from 'vue'
import { usePage }  from '@inertiajs/vue3'
import { getRender } from '../../blocks/index.js'
import FullWidthLayout from '../layouts/FullWidthLayout.vue'
import SidebarLayout   from '../layouts/SidebarLayout.vue'
import LandingLayout   from '../layouts/LandingLayout.vue'

const props   = defineProps(['page', 'blocks'])
const layouts = { 'full-width': FullWidthLayout, 'sidebar': SidebarLayout, 'landing': LandingLayout }

const currentLayout = computed(() => layouts[props.page.template.slug] ?? FullWidthLayout)
</script>
```

---

## Checklist pour créer un nouveau template

- [ ] Ajouter l'entrée dans la table `templates` (migration ou seeder)
- [ ] Ajouter le `case` dans `TemplateService::resolveComponent()`
- [ ] Créer `frontoffice/layouts/MonLayout.vue` avec les `<slot>` des zones
- [ ] Ajouter le layout dans le `layouts` object de `DynamicPage.vue`
- [ ] Ajouter une miniature dans `public/storage/templates/`
