diff --git a/docs/posting-pipeline.md b/docs/posting-pipeline.md new file mode 100644 index 0000000..b3aac66 --- /dev/null +++ b/docs/posting-pipeline.md @@ -0,0 +1,123 @@ +# Daily Entry Posting Pipeline + +Two ways to create a daily entry: the mobile frontend form at `/post`, or directly from the Grav Admin panel. Both produce the same page structure under `user/pages/01.tracker/`. + +--- + +## Frontmatter Reference + +Every entry page (`template: entry`) supports these frontmatter fields: + +| Field | Type | Required | Notes | +|---|---|---|---| +| `title` | string | ✅ | Entry headline | +| `date` | datetime | ✅ | Format: `Y-m-d H:i` (e.g. `2026-06-17 10:00`) | +| `template` | string | ✅ | Always `entry` | +| `published` | bool | ✅ | `true` to show in tracker feed | +| `lat` | string | — | Latitude decimal degrees (e.g. `52.3676`) | +| `lng` | string | — | Longitude decimal degrees (e.g. `4.9041`) | +| `location_city` | string | — | City name shown under the title (e.g. `Kyoto`) | +| `location_country` | string | — | Country name shown under the title (e.g. `Japan`) | +| `weather_desc` | string | — | Condition label — must be one of the values below | +| `weather_temp_c` | number | — | Temperature in Celsius (displayed rounded, e.g. `19`) | +| `hero_image` | string | — | Filename of the hero image (e.g. `photo.jpg`). Leave blank to auto-select the first uploaded image. | + +**`weather_desc` allowed values** (matched to emoji icons in `entry.html.twig`): +`Sunny` · `Partly cloudy` · `Cloudy` · `Foggy` · `Drizzle` · `Rain` · `Snow` · `Thunderstorm` + +**Page media (photos):** images are stored as files in the page folder (`user/pages/01.tracker//`). All images in the folder are shown in the gallery. `hero_image` pins one as the full-width header. + +**Example complete frontmatter:** +```yaml +--- +title: 'First Day in Kyoto' +date: '2026-07-20 09:30' +template: entry +published: true +lat: '35.0116' +lng: '135.7681' +location_city: 'Kyoto' +location_country: 'Japan' +weather_desc: 'Sunny' +weather_temp_c: 28 +hero_image: 'temple.jpg' +--- +``` + +--- + +## Flow 1 — Mobile Frontend Form (`/post`) + +This is the primary posting flow, designed for one-handed phone use. + +``` +Browser → /post (post-form.md) + └─ Grav Form plugin validates fields + └─ add-page-by-form plugin (onFormProcessed) + ├─ reads pageconfig.parent (/tracker) and pageconfig.slug_field (date + title) + ├─ reads pagefrontmatter (template: entry, published: true) + ├─ merges form field values into new page frontmatter + ├─ writes user/pages/01.tracker//entry.md + └─ moves uploaded photos into the page folder + └─ cache-on-save plugin (onFormProcessed) + └─ calls $grav['cache']->deleteAll() so tracker feed shows the entry immediately + └─ form shows success message, resets fields +``` + +**The form fields and their mapping to frontmatter:** + +| Form field | Frontmatter key | Notes | +|---|---|---| +| `title` | `title` | Required | +| `date` | `date` | Defaults to current datetime | +| `content` | page body (markdown) | Required | +| `photos` | page media files | Uploaded to page folder | +| `lat` | `lat` | Filled via "Get Location" button | +| `lng` | `lng` | Filled via "Get Location" button | +| `location_city` | `location_city` | Manual text entry | +| `location_country` | `location_country` | Manual text entry | +| `weather_temp_c` | `weather_temp_c` | Hidden — set by weather JS widget | +| `weather_desc` | `weather_desc` | Hidden — set by weather JS widget | + +**Slug format:** `.` (controlled by `slug_field: 'date,title'` in `post-form.md`). + +**Security:** the `/post` page requires `access: site.login: true` — anonymous visitors get redirected to login. + +--- + +## Flow 2 — Admin Panel (sit-down workflow) + +Use this for drafts, scheduled posts, or editing existing entries. + +1. Log in at `/admin` +2. Go to **Pages** → **Add Page** +3. Set: + - **Page Title:** your entry title + - **Parent Page:** `/tracker` + - **Page Template:** `entry` +4. Fill in the **Entry** tab fields (city, country, lat/lng, weather) +5. Write content in the **Content** tab +6. Upload photos via the **Media** tab +7. Set `published: true` (or leave `false` for a draft) +8. For scheduling: set `publish_date` in **Options** → **Scheduling** +9. Save + +The Admin form fields are defined by `user/themes/intotheeast/blueprints/entry.yaml`. + +**Drafts:** set `published: false` — the entry won't appear in the tracker feed until you flip it to `true`. Useful for writing ahead of time on the road. + +**Scheduling:** Grav supports `publish_date` and `unpublish_date` in page frontmatter. Set them in the Admin Options tab. Requires `pages.publish_dates: true` in `system.yaml` (already enabled). + +--- + +## Page folder structure + +``` +user/pages/01.tracker/ +└─ 2026-07-20.first-day-in-kyoto/ + ├─ entry.md ← frontmatter + markdown body + ├─ temple.jpg ← hero image (referenced by hero_image) + └─ market.jpg ← additional gallery image +``` + +The folder name follows the pattern `.`. Grav uses the folder name for ordering and routing. diff --git a/themes/intotheeast/blueprints/entry.yaml b/themes/intotheeast/blueprints/entry.yaml new file mode 100644 index 0000000..bf55e06 --- /dev/null +++ b/themes/intotheeast/blueprints/entry.yaml @@ -0,0 +1,81 @@ +title: 'Daily Entry' +'@extends': + type: default + context: blueprints://pages + +form: + fields: + tabs: + type: tabs + active: 1 + fields: + entry: + type: tab + title: Entry + fields: + header.location_city: + type: text + label: City + placeholder: 'e.g. Kyoto' + help: 'Shown under the entry title on the tracker feed' + + header.location_country: + type: text + label: Country + placeholder: 'e.g. Japan' + + col1: + type: columns + fields: + col1_lat: + type: column + fields: + header.lat: + type: text + label: Latitude + placeholder: '35.0116' + col1_lng: + type: column + fields: + header.lng: + type: text + label: Longitude + placeholder: '135.7681' + + col2: + type: columns + fields: + col2_weather: + type: column + fields: + header.weather_desc: + type: select + label: Weather Condition + default: '' + options: + '': '— none —' + 'Sunny': '☀️ Sunny' + 'Partly cloudy': '⛅ Partly cloudy' + 'Cloudy': '☁️ Cloudy' + 'Foggy': '🌫️ Foggy' + 'Drizzle': '🌦️ Drizzle' + 'Rain': '🌧️ Rain' + 'Snow': '❄️ Snow' + 'Thunderstorm': '⛈️ Thunderstorm' + + col2_temp: + type: column + fields: + header.weather_temp_c: + type: number + label: 'Temperature (°C)' + placeholder: '19' + validate: + min: -60 + max: 60 + + header.hero_image: + type: text + label: Hero Image Filename + placeholder: 'photo.jpg' + help: 'Filename of the hero/header image. Leave blank to use the first uploaded image.'