
# Mises en page, barres latérales et accès

Deux propriétés de page se situent hors de l'arbre de composants : `layout` encadre le corps, et `access` décide qui a le droit de charger la page.

## Le bloc `layout`

`layout` ne porte actuellement qu'une clé, `sidebar` — un **tableau** de sections rendues dans le `<aside>` de la page. Chaque section se lie à une table et émet une entrée par enregistrement.

| Propriété de section | Description                                                                                   |
| -------------------- | --------------------------------------------------------------------------------------------- |
| `dataSource`         | **Obligatoire.** `{ table, filter, sort }` — un sous-ensemble délibéré de la source complète. |
| `template`           | **Obligatoire.** Comment chaque enregistrement devient une entrée (voir ci-dessous).          |
| `activeIndicator`    | Met en évidence l'entrée correspondant au cadre actif.                                        |

C'est dans `template` que vivent les expressions par enregistrement :

| Propriété de `template` | Description                                                      |
| ----------------------- | ---------------------------------------------------------------- |
| `label`                 | Libellé de l'entrée, prenant en charge `$record.<field>`.        |
| `href`                  | Cible du lien, prenant en charge `$record.<field>`.              |
| `archivedField`         | Champ dont la valeur vraie masque l'entrée de la barre latérale. |

`activeIndicator` n'accepte qu'une seule valeur — `$currentUser.activeAssignment` — qui marque l'entrée correspondant au cadre courant du sélecteur de tenant.

```yaml
pages:
  - name: Workspace
    path: /workspace
    layout:
      sidebar:
        - dataSource:
            table: projects
            sort: [{ field: name, direction: asc }]
          template:
            label: '$record.name'
            href: '/workspace/$record.slug'
            archivedField: archived
          activeIndicator: '$currentUser.activeAssignment'
    components:
      - { type: container, element: main }
```

## Barres latérales liées aux données

Une barre latérale filtrée sur `$currentUser.assignments.<table>` ne rend que les enregistrements auxquels l'utilisateur connecté est affecté ; un administrateur global (`isUnrestricted`) les voit tous. Contrairement à une source de données de page, une section de barre latérale incapable de résoudre sa référence `$currentUser` est **abandonnée silencieusement** plutôt que de faire échouer la requête — la page se rend quand même, sans cette section.

## Contrôle d'accès

`access` protège la page. Elle prend l'une de quatre formes :

| Forme                     | Signification                                                              |
| ------------------------- | -------------------------------------------------------------------------- |
| `'all'`                   | Tout le monde, visiteurs anonymes compris. La valeur par défaut.           |
| `'authenticated'`         | Tout utilisateur connecté.                                                 |
| `['admin', 'editor']`     | Ces noms de rôles. Au moins une entrée.                                    |
| `{ require, redirectTo }` | L'une des formes ci-dessus comme `require`, plus une cible de redirection. |

Une entrée du tableau de rôles peut aussi être une référence de groupe, `group:<name>`, validée contre `app.auth.groups`.

```yaml
pages:
  - name: Billing
    path: /billing
    access: { require: authenticated, redirectTo: /login }
    components:
      - { type: text, tag: h1, content: 'Billing' }
```

## Ce que renvoie un refus

| Configuration              | Le visiteur anonyme ou non autorisé obtient                          |
| -------------------------- | -------------------------------------------------------------------- |
| `access` avec `redirectTo` | Un `302` vers ce chemin, avec `?redirect=<chemin d'origine>` ajouté. |
| `access` sans `redirectTo` | Un `404`, afin de ne pas divulguer l'existence de la page.           |

:::callout
**`access` ne renvoie jamais `401`.** Elle redirige ou dissimule. La seule source de `401` sur une page est une référence `$currentUser` non résolue dans une [source de données](/fr/docs/pages-data-binding#cadrage-par-utilisateur-courant) — deux mécanismes distincts, deux réponses distinctes.
:::

## Pages connexes

- [Présentation des pages](/fr/docs/pages-overview) — le tableau complet des propriétés de page.
- [Liaison de données](/fr/docs/pages-data-binding) — le cadrage `$currentUser` et son `401`.
- [Rôles et RBAC](/fr/docs/auth-roles-rbac) — les noms de rôles acceptés par `access`.
- [Groupes](/fr/docs/auth-groups) — les références `group:` acceptées par `access`.
- [Composants de mise en page](/fr/docs/layout-components) — le composant `sidebar` rendu dans le corps.
