94 lines
6.8 KiB
Markdown
94 lines
6.8 KiB
Markdown
# Blueprint Vetting — Research & Recommendation
|
||
|
||
**Status:** 📋 Not started
|
||
**Date:** 2026-07-08
|
||
**Scope:** All custom Grav blueprints (intotheeast theme page blueprints, theme blueprint, site-config extension). Stock Quark blueprints excluded.
|
||
|
||
## Files reviewed
|
||
|
||
| File | Purpose |
|
||
|---|---|
|
||
| `user/themes/intotheeast/blueprints/entry.yaml` | Daily journal entry (Admin form) |
|
||
| `user/themes/intotheeast/blueprints/story.yaml` | Story pages |
|
||
| `user/themes/intotheeast/blueprints/trip.yaml` | Trip pages |
|
||
| `user/themes/intotheeast/blueprints/home.yaml` | Home page |
|
||
| `user/themes/intotheeast/blueprints.yaml` | Theme blueprint (identity only) |
|
||
| `user/blueprints/config/site.yaml` | Site-config extension (`active_trip`, `travelling`) |
|
||
|
||
## What's already good
|
||
|
||
- Toggle idiom is correct and consistent everywhere: `options: {1: Yes, 0: No}` + `validate: type: bool`.
|
||
- `trip.yaml` `autoconnect` keys `'on'`/`'off'` are properly quoted — avoids the YAML 1.1 boolean footgun (`on:` parsing as `true:`). `default: 'on'` is quoted too.
|
||
- `user/blueprints/config/site.yaml` follows the standard Grav pattern for extending system site config (fields merge into Admin → Configuration → Site); `validation: loose` present; the `pages` field options (`start_route`, `show_root`, `show_slug`) are all real options.
|
||
- `entry.yaml` correctly uses `@extends: {type: default, context: blueprints://pages}` and adds its fields as a new tab, so entries keep the full standard Admin UI.
|
||
- Required-field validation on story/home titles and story content is in place.
|
||
- `weather_temp_c` has sensible min/max bounds (−60…60).
|
||
|
||
## Findings
|
||
|
||
### F1 — Only `entry.yaml` extends the default page blueprint (structural)
|
||
|
||
`story.yaml`, `trip.yaml`, and `home.yaml` define `form.fields.tabs` from scratch (no `@extends`). In Admin2 those page types show **only** the declared fields — no Options/Advanced tabs, so no slug rename, no ordering, no visibility, no publish dates, no taxonomy from Admin. The custom `header.published` toggles in story/trip partially compensate.
|
||
|
||
If the locked-down UI is deliberate, entry is the inconsistent one; if not, story/trip lose real capabilities (they're created repeatedly and may need slug/ordering control).
|
||
|
||
**Implementation note if extending:** story/trip use a tab key `content`, which collides with the default blueprint's Content tab — fields merge by key, so the duplicate `header.title`/`content` definitions override rather than duplicate, but the merged result needs a visual check in Admin. Their custom `header.published` toggle also becomes redundant with the default Options-tab toggle — keep one.
|
||
|
||
### F2 — `lat`/`lng` are free-text with no validation (data integrity)
|
||
|
||
`entry.yaml:27-35` and `story.yaml:64-74` declare latitude/longitude as plain `type: text`. Templates pipe the values straight into `number_format(6, …)` (`user/themes/intotheeast/templates/trip.html.twig:62`, `templates/home.html.twig:56`). PHP casts silently:
|
||
|
||
- European decimal comma `"35,0116"` → `35.000000` (marker subtly wrong)
|
||
- non-numeric garbage → `0.000000` (marker in the Gulf of Guinea)
|
||
|
||
No error surfaces anywhere. Fix: `validate: { type: float, min: -90, max: 90 }` for lat, `±180` for lng.
|
||
|
||
### F3 — `transport_mode` option drift (copy-paste divergence)
|
||
|
||
Entry offers `plane` (`entry.yaml:77`); story doesn't (`story.yaml:80-86`). The field — along with lat/lng, location, `force_connect` — is duplicated between the two blueprints, which is how drift happens. Grav supports shared partials via `import@`; in-repo example: `user/themes/quark/blueprints/blog.yaml:90` importing `partials/blog-bits.yaml`.
|
||
|
||
### F4 — `hero_image` UX inconsistency
|
||
|
||
Trip uses `pagemediaselect` (dropdown of uploaded media, `trip.yaml:40-44`); entry and story use free-text filename fields (`entry.yaml:60-64`, `story.yaml:33-37`) where a typo silently breaks the hero. `pagemediaselect` keeps the "blank = first image" fallback while removing typo risk.
|
||
|
||
### F5 — Minor items
|
||
|
||
| Item | Location | Detail |
|
||
|---|---|---|
|
||
| `travelling` default mismatch | `user/blueprints/config/site.yaml:15` | `default: false` vs option keys `1`/`0`; works via loose comparison, but `default: 0` matches every other toggle |
|
||
| Date type drift | `story.yaml:20-31` vs `trip.yaml:28-38` | story: `datetime` + `format: 'Y-m-d'` (the deliberate Admin2 datepicker fix); trip: plain `date`. Pick one convention |
|
||
| `<br>` in help text | `trip.yaml:61,73` | If Admin2 escapes HTML in help tooltips, users see literal `<br>` tags |
|
||
| `weather_temp_c` step | `entry.yaml:52-58` | HTML number inputs default to step 1 → `19.5` may be rejected client-side; fine if whole degrees are intended |
|
||
| `pagemediaselect` accept filter | `trip.yaml:42` | Extension-style `accept: ['.jpg', …]` is the filepicker convention; unverified against Admin2's SPA implementation |
|
||
|
||
## Recommendation
|
||
|
||
Treat as one small milestone in three parts, in this order:
|
||
|
||
### Phase 1 — Data-integrity + drift fixes (no decisions needed, low risk)
|
||
|
||
1. **F2:** add `validate: { type: float, min/max }` to all four lat/lng fields (entry + story).
|
||
2. **F3:** extract a shared theme partial `user/themes/intotheeast/blueprints/partials/` (e.g. `location-bits.yaml`) holding location name/country, lat/lng (with the new validation), `transport_mode` (superset incl. `plane`), and `force_connect`; `import@` it from entry and story. Follow the Quark example.
|
||
3. **F5 quick fixes:** `travelling` default → `0`; standardize date fields on `datetime` + `format: 'Y-m-d'` (matches the established Admin2 datepicker fix).
|
||
|
||
### Phase 2 — Structural decision (needs Mischa's call)
|
||
|
||
4. **F1:** recommended: add `@extends: default` to **story and trip** (repeatedly-created content pages that benefit from slug/ordering/options control); leave **home** minimal (singleton whose slug must never change). Resolve the Content-tab merge and duplicate-published-toggle notes above. Verify each Admin form visually after the change.
|
||
5. **F4:** switch entry + story `hero_image` to `pagemediaselect` (naturally bundles with the Phase 2 Admin verification pass).
|
||
|
||
### Verify-once checklist (manual, 5 minutes in Admin2)
|
||
|
||
- [ ] Trip page → Cover Image dropdown: do `.gpx` files appear? (If yes, the `accept` filter isn't applying — F5.)
|
||
- [ ] `use_gpx` / `autoconnect` help tooltips: rendered line breaks or literal `<br>`?
|
||
- [ ] Decide: whole-degree temperatures OK, or add `step` to `weather_temp_c`?
|
||
|
||
### Out of scope
|
||
|
||
- Post form (`/post`) field parity — separate surface, not touched by this vetting.
|
||
- Theme blueprint (`blueprints.yaml`) — minimal but valid; no theme options exist yet, nothing to add.
|
||
|
||
## Open questions
|
||
|
||
1. **F1:** Is the locked-down Admin UI for story/trip/home deliberate? (Recommendation above assumes it isn't for story/trip.)
|
||
2. Should `transport_mode` for stories include `plane` (superset) or stay intentionally narrower?
|