Navigation and the dashboard
Source: lib/cafe_car/navigation.rb, app/views/application/_navigation.html.haml
and _navigation_links.html.haml (in the gem).
The sidebar is route-driven — there is no menu registry
The sidebar lists every named index route in the app (Rails internals excluded),
grouped by namespace (admin/… routes render under an “Admin” heading). So:
- Add a sidebar link: add
cafe_car :things(or anyresources) to the routes. That’s it. - Remove one: don’t draw an index route (
cafe_car :things, except: :indexoronly:what you need).
The current page’s link highlights automatically (current/ancestor classes).
Icons come from the locale
navigation.icon.<controller_name> maps a controller to an
Iconoir icon name:
en:
navigation:
icon:
products: box-iso
invoices: page-flip
No key, no icon — the link still renders.
Customizing
Override the partials like any other (views.md):
app/views/application/_navigation.html.haml— the whole sidebar (dashboard link, route links, session link).app/views/application/_navigation_links.html.haml— just the grouped route list; thenavigationhelper exposesnavigation.groups/navigation.routes.- A per-resource
_navigation.html.hamlchanges (or, if empty, hides) the sidebar for that resource’s pages only.
The dashboard — opt in by writing one view
No template, no dashboard: the route always exists, but it 404s and shows no nav
link until the host writes app/views/cafe_car/dashboard/show.html.haml. The page
uses ordinary Pundit authorization:
class DashboardPolicy < ApplicationPolicy
def show? = user.present?
end
Then write the view:
- title "Dashboard"
= Page title: "Dashboard" do |page|
= page.Body do
.Dashboard
= metrics Article
= metric("Signups today") { User.where(created_at: Date.current.all_day).count }
= chart "New articles", model: Article, x: :created_at, by: :month
metrics(Model)— one count tile per scope named in the model policy’spermitted_metrics(:all= the whole policy scope). Policy-driven; the default choice.metric("Label") { … }— one tile with whatever the block returns.chart "Title", model:, x:, by:— the inline-SVG bar chart, bucketing over thexdate column at:day/:week/:month. Column names are validated against the policy’s date columns, and rows come frompolicy_scope(model)— never raw SQL or unscoped data.
It’s a plain view: add headings, your own partials, anything between tiles. Once the file exists a Dashboard link appears at the top of the sidebar.