dmvcframework-ui
Skill23 starsChanged 7 days agoApache-2.0View on GitHub
Use when styling or laying out the HTML of a DMVCFramework web application — adding a page, a nav entry, a card, a form, a toast, a theme toggle, or touching style.css. Covers the presentation layer the DMVCFramework wizard actually generates: Bootstrap 5.3 (loaded from CDN in baselayout), the brand tokens in style.css, dark/light mode via data-bs-theme, and the HTMX activity classes. Triggers on "style.css", "Bootstrap", "dark mode", "theme toggle", "navbar", "card", "toast", "hero", "CSS", "layout", "responsive", "look and feel", "brand colors".
1 other project uses a version of this.
Adopted by
Most recently taken up by
- danieleteti/delphimvcframeworkword for word, first seen Nov 2, 2026
Other versions1 project uses a version of this.
Word for word · 1
- danieleteti/delphimvcframework★ 1.4k100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository15 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- delphi-buildSkill
- delphi-code-smellsSkill
- delphi-firedacSkill
- delphi-securitySkill
- delphiSkill
- delphi-testingSkill
- dmvcframework-jsonrpcSkill
- dmvcframework-minimal-apiSkill
- dmvcframework-securitySkill
- dmvcframeworkSkill
- dmvcframework-testingSkill
- dmvcframework-webappSkill
- exewatch-delphiSkill
- htmx-skillSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 2 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 9
Before writing any markup or CSS, know these three facts:
- Very specific: line 33
Never invent an identifier or answer from memory.
- Distinctive: line 38
If you still cannot verify it, say so.
- Very specific: line 44
Every page does {{extends "../baselayout.html"}} and fills blocks.
- Very specific: line 105
Keep aria-current — it is what a screen reader announces.
- Very specific: line 197
Do not hand-build a JSON string for the payload — you get a *quoted string* on the client, not an object.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
DMVCFramework — UI layer (Bootstrap 5.3 + style.css)
The wizard's web application ships a complete presentation layer. Use it — do not invent one. Before writing any markup or CSS, know these three facts:
- Bootstrap 5.3 is already loaded from CDN in
baselayout.html(CSS in<head>,bootstrap.bundle.min.jsbefore</body>). Every stock component — grid, cards, navbar, buttons, forms, alerts, badges, modals, spinners, toasts — is available. Do not add another CSS framework, and do not hand-roll what Bootstrap has. style.cssis deliberately small (~100 lines). It is not a design system: it sets brand tokens, repaints Bootstrap's primary colour, and adds four helpers. Read it before adding anything to it.- Dark mode is Bootstrap's, driven by
data-bs-themeon<html>. Never write a.dark-modeclass or aprefers-color-schememedia query — use Bootstrap's theme-aware variables and they follow the toggle for free.
STOP — this skill works inside a wizard-generated project. It describes the layout and stylesheet the
DMVCFramework IDE wizard produces. If there is no wizard project in the current folder (no
bin/templates/baselayout.html, no bin/www/css/style.css), stop and tell the user to create one first
(Delphi IDE → File → New → Other → Delphi Projects → DelphiMVCFramework → New DMVCFramework Application,
preset Web Application, defaults accepted — the server backend is Indy Direct), then cd into the
folder and start you there. Read baselayout.html and style.css before writing any markup or CSS.
COMPANION SKILL: dmvcframework-webapp — the server side (TemplatePro syntax, RenderView, ViewData,
HTMX, controllers). This skill is only about what the browser renders.
When in doubt about an API — verify it, never guess
Never invent an identifier or answer from memory. If you need a signature this skill does not cover, ask the
user for the path to their DelphiMVCFramework checkout and read sources/ (and the matching samples/
project); failing that, read the official repository —
sources ·
samples.
If you still cannot verify it, say so. Where a skill and a sample disagree, the sample wins.
1. What baselayout.html gives you
Every page does {{extends "../baselayout.html"}} and fills blocks. The layout already provides the
<!DOCTYPE>, <head>, the navbar, <main class="container">, the footer, the toast container, Bootstrap's
JS, the theme toggle and the no-flash theme restore script.
Blocks you override:
| Block | Purpose |
title | Page title in the browser tab |
body | The page content — this is the one you always fill |
extra_css | Extra <link>/<style> for this page only |
scripts | Page-specific <script> before </body> |
extra_js | Extra JS after scripts |
Variables the controller sets (available in any template): app_name, dmvc_version, current_year,
page_id.
A new page is just this:
{{extends "../baselayout.html"}}
{{block "title"}}Customers{{endblock}}
{{block "body"}}
<h1 class="mb-4">Customers</h1>
<div class="row g-3">
{{for c in customers}}
<div class="col-md-4">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">{{:c.FirstName}} {{:c.LastName}}</h5>
<p class="card-text text-secondary">{{:c.Email}}</p>
</div>
</div>
</div>
{{endfor}}
</div>
{{endblock}}No <html>, no <head>, no stylesheet link, no container div. The layout owns those.
2. The navbar — adding an entry
Nav links live in baselayout.html. The active state is driven by page_id, which the controller sets:
<li class="nav-item">
<a class="nav-link {{if page_id|eq,"customers"}}active{{endif}}"
{{if page_id|eq,"customers"}}aria-current="page"{{endif}}
href="/web/customers">Customers</a>
</li>ViewData['page_id'] := 'customers';Keep aria-current — it is what a screen reader announces. The nav is navbar-expand-md: it collapses into
the burger toggler below md, which already works. Do not remove the toggler.
3. Theme (dark / light)
<html data-bs-theme="dark"> is the default; a toggle button in the navbar flips it and persists the choice in
localStorage['dmvc-theme'], and an inline script in <head> restores it before first paint (no flash).
To make your markup theme-aware, use Bootstrap's semantic classes and variables — never hard-coded colours:
| Instead of | Use |
background: #fff | class="bg-body" / bg-body-tertiary |
color: #333 | class="text-body" / text-secondary |
border: 1px solid #ddd | class="border" |
| a custom colour in CSS | var(--bs-body-bg), var(--bs-border-color), var(--bs-secondary-color) |
These all flip automatically with the theme. A literal hex does not.
4. style.css — what is in it, and what to add
:root {
--brand-accent: #fbbf24; /* amber-400 — the brand colour */
--brand-accent-strong: #d4991a;
--brand-font-body: 'Outfit', system-ui, sans-serif;
--brand-font-mono: 'JetBrains Mono', ui-monospace, monospace;
}- Bootstrap's primary is repainted to the accent (
--bs-primary,--bs-link-color), so.btn-primary,.text-primaryand links are already gold. Usebtn-primary; do not write a custom gold button. (Note the file also overrides.btn-primary's own--bs-btn-*vars explicitly — Bootstrap 5.3 bakes button colours at compile time, so overriding--bs-primaryalone would not repaint them.) - Fonts: Outfit for body, JetBrains Mono for
code/pre/kbd/samp, imported from Google Fonts.
The four helpers it defines — use them instead of reinventing:
| Class | What it is |
.hero | Centred landing block with a subtle accent gradient. <div class="hero"><h1>…</h1><p class="lead">…</p></div> |
.section-label | Small mono uppercase marker above a section |
.badge.brand-mono | Monospace badge, for versions/ids |
.htmx-request / .htmx-indicator | HTMX activity: the element dims while its request is in flight; .htmx-indicator shows only during it |
Before adding a rule to style.css, check in this order: does a Bootstrap utility do it (spacing m-*/p-*,
flex d-flex, text, colour)? Does a Bootstrap component do it? Only then write CSS — and write it against the
brand tokens and --bs-* variables, not literals.
5. Toasts
The layout defines #toastContainer and a global showToast(message, type) — type is success, danger,
warning or info. message goes into innerHTML: it is HTML, not text. A fixed string chosen by the
server is safe; anything a user typed (a name, a title) must be escaped first, or it is a DOM XSS.
From an HTMX response, trigger it with a client event from Delphi:
uses MVCFramework.HTMX;
// The payload is serialized as a JSON *value*. A string arrives at the client as evt.detail.value —
// NOT as evt.detail.<something>. This is the shape the framework's own sample uses.
Context.Response.HXTriggerClientEvent('showMessage', 'Customer saved');{{# in the page's "scripts" block #}}
<script>
document.body.addEventListener('showMessage', function (evt) {
showToast(evt.detail.value, 'success');
});
</script>Need structured data instead of a plain string? Pass an object and read its properties:
Context.Response.HXTriggerClientEvent('customerSaved', lCustomer); // a Delphi objectfunction escapeHtml(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }
document.body.addEventListener('customerSaved', function (evt) {
showToast('Saved ' + escapeHtml(evt.detail.FirstName), 'success');
});Do not hand-build a JSON string for the payload — you get a quoted string on the client, not an object.
And do not write your own toast markup or alert().
6. Forms
Stock Bootstrap, plus HTMX for the submit. Server-side validation errors come back as HTML.
<form hx-post="/web/customers" hx-target="#form-wrap" hx-swap="outerHTML" class="row g-3">
<div class="col-md-6">
<label for="firstName" class="form-label">First name</label>
<input type="text" class="form-control {{if errors.FirstName}}is-invalid{{endif}}"
id="firstName" name="firstName" value="{{:customer.FirstName}}" required>
{{if errors.FirstName}}<div class="invalid-feedback">{{:errors.FirstName}}</div>{{endif}}
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>is-invalid + .invalid-feedback is Bootstrap's error pattern — it needs no JS. Every input needs a <label for>.
In a wizard project prefer the generated forms library, bin/templates/lib/forms_bootstrap5.tpro
({{import "../lib/forms_bootstrap5.tpro" as f}} from a page in a subfolder — the path is relative to the page —
then f.input, f.select, f.checkbox, …): it writes this
markup and reads values from formModel and messages from formErrors, both keyed by the control's name.
Whatever you use, the error-map keys must be the ones the server fills — the wizard's convention is the
lowercase field name (server side: the dmvcframework-webapp skill, "Form posts").
7. Common mistakes
| Mistake | Why it is wrong |
| Adding Tailwind / Pico / a second framework | Bootstrap 5.3 is already loaded. Two frameworks = two resets fighting. |
| Writing a custom grid / flexbox layout | row/col-*, d-flex, gap-* already exist. |
Hard-coded #fff / #333 in CSS or style="" | Breaks in the other theme. Use bg-body / text-body / --bs-* vars. |
A .dark-mode class or prefers-color-scheme query | Dark mode is data-bs-theme. Yours will not follow the toggle. |
| A custom gold button | .btn-primary is already the brand accent. |
| Hand-rolled toast / modal / dropdown | Bootstrap ships them; showToast() is already global. |
<link>ing style.css or Bootstrap in a page template | The layout does it. A child template only fills blocks. |
Restyling .htmx-request | It is already wired to the HTMX request lifecycle. |
8. Files
| File | What it is |
bin/templates/baselayout.html | The layout: head, navbar, main, footer, toasts, theme toggle, Bootstrap JS |
bin/www/css/style.css | Brand tokens, primary override, 4 helpers, HTMX classes (~100 lines) |
bin/www/ | Static root, served at /static by FileServerBundle (TMVCStaticFilesMiddleware in a 3.4 project) |
Bootstrap docs: https://getbootstrap.com/docs/5.3/ — read the component page rather than guessing class names.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

