customization
Customization and polish
Export
Each index exports its current scoped-and-filtered view. The toolbar offers the enabled formats, and the export honours the active scope, filters, and sort.
GET /admin/<resource>/export.csvstreams a CSV: a header row of column labels followed by one row per record, with values quoted when they contain a comma, quote, or newline. It is sent as a download attachment and streamed rather than buffered, so large result sets do not build a single string in memory.GET /admin/<resource>/export.jsonreturns the same view as JSON, rendered through the controller's custom-renderer registry. Each object carries the column values.GET /admin/<resource>/export.xmlreturns the same view as XML through the renderer registry, one<record>per row.
Export columns
By default the export uses the index columns. A csv block declares an explicit
set of export columns instead, applied to CSV, JSON, and XML alike:
csv({
column('title');
column('author', :display({ .author.name }));
});Limiting the formats
The export is on by default with all three formats. Restrict or disable it per
resource with the export option:
MVC::Keayl::Admin.register(Post, { ... }, export => <csv json>); # only CSV and JSON
MVC::Keayl::Admin.register(Log, { ... }, export => False); # no exportOnly the offered formats get a route and a toolbar link; a disabled format is a 404.
Standalone pages
A page has no backing model. It is registered with a block that returns HTML, rendered inside the admin layout, and added to the menu:
MVC::Keayl::Admin.page('reports', -> $controller {
'<div class="card"><div class="card-body">Sales summary</div></div>'
}, title => 'Reports', group => 'Tools', icon => 'graph-up');The block receives the controller, so it can read params or the current admin.
Pass :hide to register the route without a menu entry. Page menu entries honour
the same group, priority, and icon options as resources. A page's icon
also appears in its heading, the same as a resource's icon.
Localization
All chrome, resource names, attribute labels, scope names, and action labels go
through an I18n backend. Without translations they fall back to the humanized
English defaults, so localization is opt-in. Humanizing title-cases each word and
drops a trailing _id or _at suffix, so author_id becomes Author and
created_at becomes Created.
Load locale files and select a locale:
MVC::Keayl::Admin.load-locales('config/locales');
MVC::Keayl::Admin.locale('fr');The lookup keys are:
activerecord.models.<model>andactiverecord.attributes.<model>.<attr>for resource and attribute names (shared with the ORM's conventions).keayl_admin.chrome.<key>for chrome strings such asdashboard,actions,show,edit,delete,new,filters, andno-records.keayl_admin.scopes.<name>for scope tab labels.keayl_admin.actions.<name>for custom action labels.
Theming
Host view overrides
Register a view path that is searched before the engine's own views. A host template at the same name overrides the engine's:
MVC::Keayl::Admin.view-path('app/views/admin');A file at app/views/admin/resource/index.html.haml then replaces the built-in
index template, and likewise for any partial.
CSS variables
The admin layers a small stylesheet over the Bootstrap bundle that exposes a set of CSS variables:
--keayl-admin-sidebar-bg--keayl-admin-sidebar-width--keayl-admin-navbar-bg--keayl-admin-accent--keayl-admin-body-bg
Override them with a host stylesheet, which is loaded after the theme so its values win:
MVC::Keayl::Admin.use-stylesheet('/assets/admin-theme.css');:root {
--keayl-admin-navbar-bg: #1b1e21;
--keayl-admin-accent: #6f42c1;
}