Skip to content

How It Works

abbas0444 edited this page Sep 25, 2026 · 3 revisions

How It Works

A short tour of what the app stores and how each feature reaches the screen. You do not need any of this to use the app.

Record types the app owns

Record type Purpose
Theme Definition One theme: 11 colours, font, size, weight, corner radius, animation speed, hover lift, owner, public flag, role restrictions. The 17 bundled ones are marked Is Default and ship as fixtures.
User Theme Preference One row per person: the active theme, the mode (Single or Automatic), the dark theme for Automatic, per-user colour overrides, the density, and the Use Frappe's Built-in Theme opt-out.
User Sound Preference + User Sound Mapping One row per person with the master switch and a child row per event (file and volume).
Theme Settings The single site-wide settings record.
Allowed Theme, Theme Role Child tables behind Allowed Themes and Restrict to Roles.

How a theme reaches the screen

The active theme is placed in the page's boot data, so the first paint is already themed. The theme manager script writes the theme's values into CSS variables on the page and marks the page light or dark; Frappe's own components pick the variables up. Frappe's built-in Switch Theme dialog is extended so Nexus themes appear there, and choosing one of Frappe's own themes hands control back cleanly.

When Apply to Login & Website is on, the same CSS variables are injected into the login page and public web pages from the site default theme.

How the command palette finds things

Everything under Go to comes from the boot data Frappe already sends to every Desk page — the record types you may read and create, your reports, pages and workspaces — so opening the palette costs no request. Recent reads Frappe's own recent list and this session's route history. Search calls Frappe's global search with your permissions, after a short pause in typing, and ignores any reply that arrives for an earlier query. Theme names are fetched once per minute when the palette is open.

How density reaches the screen

Your density travels in the boot data and is written as html[data-density] before anything draws; a copy in the browser covers the moment before boot on a reload. A stylesheet keyed on that attribute redefines Frappe's own height and padding variables and a set of selectors for rows, fields, buttons and sidebar items. Comfortable sets no attribute, so it is Frappe's own spacing untouched.

How the "What's new" card decides

The release notes live in the app's code, keyed by version. Boot carries whether the signed-in person has seen the running release series; the card shows once, and dismissing it stores the version as a user default and clears that person's boot cache. Patch releases never show it.

How a sidebar skin reaches the screen

The theme's sidebar settings travel with the rest of the theme. The theme manager works out any colour left on Auto (the same calculation the server uses for its contrast check), writes them into four CSS variables and marks the page with the style. A stylesheet keyed on that mark paints Frappe 16's sidebar, or Frappe 15's top bar. Module icon colours come from a small script that tags each sidebar item with its module as the sidebar is drawn.

How the mini rail works

On Frappe 16 the rail is Frappe's own collapsed sidebar: the app saves your choice, draws the sidebar in that state from the first paint, adds the shortcut and the hover peek, and saves Frappe's own chevron and Ctrl+/ too. On Frappe 15 the same choice hides the side column of each page.

How the home page becomes the landing

When it is switched on, the boot data sent to the Desk names the home page as the page to open for an empty address, which is how Frappe itself picks its landing. Nothing is stored, so switching it off restores Frappe's own landing on the next load.

How a sound plays

The sound manager script wraps Frappe's sound player: it swaps in your chosen file per event, applies the volume, honours the master switch and cuts every sound at three seconds. The app registers its own audio element for every event, so it never depends on Frappe's stock sound files staying in place.

How the Permission Inspector reads and writes

It reads through Frappe's own helpers (get_valid_perms, get_all_perms, get_roles, has_permission) and writes through Custom DocPerm, the same mechanism the stock Role Permission Manager uses. It has no tables and no permission logic of its own; if it were removed, nothing about your permissions would change.

Dependencies between actions follow Frappe's validation rules: Submit, Cancel and Amend need Edit; Cancel needs Submit; Import needs Create. The page cascades these for you and says so, and the server applies the same rules, so a batch that contradicts itself is refused as a whole.

Safety checks on saved data

  • Colour and style values are validated before they are stored, so no CSS can be injected through a theme, even a shared one.
  • Every saved theme must pass the contrast checks (4.5 : 1 for text, 3.0 : 1 for button text).
  • Sound URLs must point at files this site serves; an outside address is refused.
  • Imported theme files are validated field by field.
  • Every Permission Inspector request checks for the System Manager role on the server before doing anything.

What installation changes on a site

The Theme User role, two entries in Navbar Settings, a Desktop Icon, the Nexus Theme workspace, the app's own DocTypes and the bundled themes. Frappe's permission records are never touched by installing or uninstalling.

Clone this wiki locally