Admin setup
Step-by-step guide to enable the admin interface in an existing Runique project.
Prerequisites
- A working Runique project with a configured database
- A
usersmodel withis_staffandis_superuserfields (generated bymodel!) - The
runiquebinary installed (cargo install runiqueorcargo buildfrom the workspace)
Step 1 β Create `src/admin.rs`
This file declares administrable resources via the admin! macro:
// src/admin.rs
use crate::entities::{users, articles};
use crate::forms::{RegisterForm, ArticleForm};
admin! {
users: users::Model => RegisterForm {
title: "Users",
},
articles: articles::Model => ArticleForm {
title: "Articles",
}
}
Step 2 β Generate `src/admins/` with the daemon
runique start
The daemon reads src/admin.rs, generates src/admins/ and launches cargo run.
The src/admins/ folder is created automatically β do not edit it manually.
src/admins/
βββ README.md
βββ mod.rs
βββ admin_panel.rs
If
src/admins/already exists from a previous generation,runique startregenerates it.
Step 3 β Declare the module in `src/main.rs`
mod admin;
mod admins; // module generated by runique start
Step 4 β Wire `.with_admin()` in the 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?;
| Method | Role |
|---|---|
.prefix("/admin") | Admin route prefix (default: /admin) |
.site_title("β¦") | Title displayed in the interface |
.auth(RuniqueAdminAuth::new()) | Admin authentication (default) |
.routes(admins::routes("/admin")) | Mounts CRUD routes under /admin |
.with_state(β¦) | Shared state generated by the daemon |
.no_robots_txt() | Disables the automatic /robots.txt |
.extra_routes(vec![β¦]) | Custom routes protected by the admin middleware |
Automatic robots.txt β When the admin panel is active, Runique automatically serves a
/robots.txtroute containingDisallow: /admin/to exclude the interface from search engines. The prefix configured via.prefix()is respected. Use.no_robots_txt()if you want to manage this file yourself.
Custom admin routes (`extra_routes`)
For business views that go beyond the generated CRUD (e.g. order detail with related lines,
custom dashboard), declare extra routes in url.rs and register them via .extra_routes().
These routes automatically inherit the admin middleware: authentication, AdminState,
PrototypeAdminState (sidebar), and CurrentUser.
url.rs
pub fn admin_extra_routes() -> Vec<(&'static str, runique::axum::routing::MethodRouter)> {
vec![
("/orders/{number}/detail", view!{ admin_order_detail }),
]
}
main.rs
.with_admin(|a| a
.routes(admins::routes("/admin"))
.extra_routes(url::admin_extra_routes())
)
Paths are relative to the admin prefix β /orders/{number}/detail becomes
/admin/orders/{number}/detail.
Handler β retrieve the extensions injected by the middleware:
use runique::prelude::*;
use runique::admin::{AdminState, PrototypeAdminState, inject_admin_prefix, insert_admin_messages};
pub async fn admin_order_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());
// β¦ business logic β¦
request.render("admin/order_detail.html")
}
The template must extend admin_base to inherit the CSS and sidebar:
{% extends "admin_base" %}
Step 5 β Create a superuser
runique create-superuser
Follows an interactive wizard to create the first admin account (is_superuser = true).
Accessing the interface
Once the server is running, the interface is available at:
http://localhost:{PORT}/admin/
The /admin/login page redirects to the dashboard if credentials are valid.