Mise en place de l'admin
Guide pas à pas pour activer l'interface d'administration dans un projet Runique existant.
Prérequis
- Un projet Runique fonctionnel avec une base de données configurée
- Un modèle
usersavec les champsis_staffetis_superuser(générés parmodel!) - Le binaire
runiqueinstallé (cargo install runiqueoucargo builddu workspace)
Étape 1 — Créer `src/admin.rs`
Ce fichier déclare les ressources administrables via la macro admin! :
// src/admin.rs
use crate::entities::{users, articles};
use crate::formulaire::{RegisterForm, ArticleForm};
admin! {
users: users::Model => RegisterForm {
title: "Utilisateurs",
},
articles: articles::Model => ArticleForm {
title: "Articles",
}
}
Étape 2 — Générer `src/admins/` avec le daemon
runique start
Le daemon lit src/admin.rs, génère src/admins/ et lance cargo run.
Le dossier src/admins/ est créé automatiquement — ne pas le modifier manuellement.
src/admins/
├── README.md
├── mod.rs
└── admin_panel.rs
Si
src/admins/existe déjà depuis une génération précédente,runique startle régénère.
Étape 3 — Déclarer le module dans `src/main.rs`
mod admin;
mod admins; // module généré par runique start
Étape 4 — Câbler `.with_admin()` dans le builder
use runique::app::builder::RuniqueAppBuilder as builder;
RuniqueApp::builder(config)
.routes(url::routes())
.with_database(db)
.with_admin(|a| {
a.site_title("Administration")
.auth(RuniqueAdminAuth::new())
.routes(admins::routes("/admin"))
.with_state(admins::admin_state())
})
.build()
.await?
.run()
.await?;
| Méthode | Rôle |
|---|---|
.prefix("secret") | Segment monté devant l'admin (défaut : aucun) — voir ci-dessous |
.site_title("…") | Titre affiché dans l'interface |
.auth(RuniqueAdminAuth::new()) | Authentification admin (par défaut) |
.routes(admins::routes("/admin")) | Monte les routes CRUD sous /admin |
.with_state(…) | État partagé généré par le daemon |
.no_robots_txt() | Désactive le /robots.txt automatique |
.extra_routes(vec![…]) | Routes custom protégées par le middleware admin |
.routes() et .prefix() — deux réglages distincts
.routes(admins::routes("/site-admin")) définit où vit l'admin.
.prefix("secret") définit ce qui est monté devant. Ils se composent :
routes(...) | .prefix(...) | URL de l'admin |
|---|---|---|
/site-admin | — | /site-admin/… |
/site-admin | secret | /secret/site-admin/… |
| (non appelé) | secret | /secret/admin/… (chemin par défaut) |
L'ordre des deux appels n'a aucune importance, et les slashs sont optionnels :
secret, /secret et /secret/ sont équivalents.
Note de version —
.prefix()remplaçait auparavant le chemin de l'admin, ce qui la mettait en concurrence avec.routes(): le dernier appelé gagnait, et inverser les deux lignes changeait silencieusement les URLs servies. Elle préfixe désormais, conformément à son nom. Un projet qui utilisait.prefix("/backoffice")pour renommer l'admin doit passer ce chemin àadmins::routes("/backoffice").
robots.txt automatique — Quand l'admin est actif, Runique génère automatiquement une route
/robots.txt(ligneSitemap:si.sitemap(…)est défini, plus les signauxContent-Signal). Utilisez.no_robots_txt()si vous souhaitez gérer ce fichier vous-même.Le préfixe admin n'y figure pas, volontairement.
robots.txtest un fichier public : y écrireDisallow: /mon-prefixe/publierait justement le chemin qu'un préfixe personnalisé cherche souvent à garder discret. EtDisallowdemande de ne pas parcourir, pas de ne pas indexer — une URL connue par ailleurs peut apparaître malgré tout dans les résultats.L'exclusion est assurée par l'en-tête
X-Robots-Tag: noindex, nofollow, posé par Runique sur toutes les réponses de l'admin — page de login incluse, ainsi que les redirections, les erreurs et les réponses JSON. Il ne divulgue aucun chemin et reste en place même si vous surchargez les templates admin.
Routes admin custom (`extra_routes`)
Pour des vues métier qui dépassent le CRUD généré (ex : détail commande avec lignes associées,
tableau de bord personnalisé), déclarez des routes supplémentaires dans url.rs et
enregistrez-les via .extra_routes().
Ces routes héritent automatiquement du middleware admin : authentification, AdminState,
PrototypeAdminState (sidebar), et CurrentUser.
url.rs
pub fn admin_extra_routes() -> Vec<(&'static str, runique::axum::routing::MethodRouter)> {
vec![
("/commandes/{numero}/detail", view!{ admin_commande_detail }),
]
}
main.rs
.with_admin(|a| a
.routes(admins::routes("/admin"))
.extra_routes(url::admin_extra_routes())
)
Les chemins sont relatifs au préfixe admin — /commandes/{numero}/detail devient
/admin/commandes/{numero}/detail.
Handler — récupérer les extensions injectées par le middleware :
use runique::prelude::*;
use runique::admin::{AdminState, PrototypeAdminState, inject_admin_prefix, insert_admin_messages};
pub async fn admin_commande_detail(
Extension(admin): Extension<Arc<AdminState>>,
Extension(proto): Extension<Arc<PrototypeAdminState>>,
mut request: Request,
) -> AppResult<Response> {
inject_admin_prefix(&mut request, &admin.config.prefix);
insert_admin_messages(&mut request, proto.registry.all());
// … logique métier …
request.render("admin/commande_detail.html")
}
Le template doit étendre admin_base pour hériter du CSS et de la sidebar :
{% extends "admin_base" %}
Étape 5 — Créer un superuser
runique create-superuser
Suit un assistant interactif pour créer le premier compte admin (is_superuser = true).
Accès à l'interface
Une fois le serveur démarré, l'interface est disponible à :
http://localhost:{PORT}/admin/
La page /admin/login redirige vers le dashboard si les identifiants sont valides.