docs: add new-app guide and EJS layout skeleton
Lint / JS (eslint) (push) Successful in 13s

README.md:
- Add 'Starting a New App' section with step-by-step instructions:
  nginx alias setup, which skeleton to copy, how to define nav for
  each framework, app.css pattern, lt.init() call
- Update File Structure section: remove app-specific labels from
  framework skeletons (was 'PHP / Tinker Tickets' etc.), add
  layout.ejs to the node/ listing

node/layout.ejs:
- New EJS base layout skeleton matching the PHP/Python equivalents:
  generic nav via navLinks locals, lt-* class names throughout,
  CSP nonce on all script tags, pageStyles/pageScripts arrays,
  CURRENT_USER + CSRF_TOKEN globals injected at runtime

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-18 14:00:01 -04:00
parent 75c57092f8
commit 19d6a2883c
2 changed files with 246 additions and 8 deletions
+100 -8
View File
@@ -895,18 +895,110 @@ Set `data-theme="light"` on `<html>` directly. All component styles react throug
---
## Starting a New App
### 1. Serve the design system files
Add an nginx alias so every app on the same host can reference the same files:
```nginx
# In each app's server block (or a shared include):
location /web_template/ {
alias /path/to/web_template/;
expires 7d;
add_header Cache-Control "public, immutable";
}
```
Then in your HTML:
```html
<link rel="stylesheet" href="/web_template/base.css">
<script src="/web_template/base.js"></script>
```
### 2. Copy the right skeleton
| Stack | Copy this file | Into your app as |
|-------|---------------|-----------------|
| PHP | `php/layout.php` | `views/layout.php` (or `layout_header.php`) |
| Python/Flask | `python/base.html` | `templates/base.html` |
| Node/Express | `node/middleware.js` + `node/layout.ejs` | `middleware.js` + `views/layout.ejs` |
### 3. Define your nav
**PHP** — pass `$navLinks` before including the layout:
```php
$navLinks = [
['href' => '/', 'key' => 'dashboard', 'label' => 'Dashboard'],
['href' => '/reports', 'key' => 'reports', 'label' => 'Reports'],
['label' => 'Admin', 'key' => 'admin', 'adminOnly' => true, 'children' => [
['href' => '/admin/users', 'label' => 'Users'],
]],
];
$activeNav = 'dashboard';
include __DIR__ . '/views/layout.php';
```
**Python/Flask** — inject via context processor or pass directly to `render_template`:
```python
nav_links = [
{'href': url_for('index'), 'key': 'dashboard', 'label': 'Dashboard'},
{'href': url_for('settings'), 'key': 'settings', 'label': 'Settings'},
]
return render_template('page.html', nav_links=nav_links)
```
**Node/Express** — set on `res.locals` via `injectLocals` middleware:
```js
app.use((req, res, next) => {
res.locals.navLinks = [
{ href: '/', key: 'dashboard', label: 'Dashboard' },
{ href: '/workers', key: 'workers', label: 'Workers' },
];
next();
});
```
### 4. Add app-specific CSS
Create `app.css` in your app. Import nothing from `base.css` — just override tokens or add components:
```css
/* app.css — app-specific extensions only */
:root {
--app-accent: #FF6B00; /* override if needed */
}
/* Only put styles here that aren't already in base.css */
```
### 5. Initialise
In your base template, after `base.js`:
```html
<script nonce="{{ nonce }}">
lt.init({ bootName: 'MY APP' });
</script>
```
---
## File Structure
```
web_template/
├── base.css Design system styles (79 sections, ~5,200 lines)
├── base.js Design system JS (55+ modules, ~2,800 lines)
├── base.html Living reference template
├── README.md This file
── (framework skeletons)
├── php/ PHP / Tinker Tickets
├── python/ Flask / Jinja2 / GANDALF
└── node/ Express / EJS / PULSE
├── base.css Design system styles (79 sections, ~5,200 lines)
├── base.js Design system JS (55+ modules, ~2,800 lines)
├── base.html Living component reference — open in browser to browse everything
├── README.md This file
── AUTHELIA_INTEGRATION.md Theming Authelia portal with this design system
└── framework skeletons/
├── php/
│ └── layout.php Generic PHP base layout (pass $navLinks)
├── python/
│ ├── base.html Jinja2 base template (pass nav_links list)
│ └── auth.py Authelia SSO helper for Flask
└── node/
├── middleware.js Express middleware (auth, CSRF, nonce, rate limit)
└── layout.ejs EJS base template (uses res.locals.navLinks)
```
---