Files
intotheeast-com/docs/guides/gpx-manager.md
m038andClaude Opus 5 ed6e43ae51 docs: trim CLAUDE.md 305->179 lines; extract code descriptions to docs/
CLAUDE.md is loaded into context on every request, so every line has a
recurring cost. Applies one rule to decide what earns its place: keep what
changes behaviour (rules and gotchas Claude cannot discover before it acts);
extract what merely describes code (Claude reads the code anyway, and prose
about code silently drifts).

The four stale facts fixed in the previous commit were all in the
"describes code" class -- active_trip, the Admin2 version, demo-load's
scope, the gitignore list. None were rules. That is the argument for moving
this material next to what it documents.

Extracted (kept as pointers):
- entry-map + trip-feed-col parameter contracts (56 lines) -> reference/
  architecture.md "Shared partial contracts". CLAUDE.md keeps only the
  invariants: single map path, must assign window.tripMap/homeMap, keep
  trip-feed-col single-purpose, initTripStats depends on MapUtils.
- Prod override runbook (49 -> 9 lines) -> guides/deploy-cycle.md "The env
  override tree", incl. the Twig dev/prod table and WEB_HOST. CLAUDE.md
  keeps the two behavioural rules: never commit prod values, and Admin on
  the server writes to the env tree (so check both config paths, env wins).
- GPX API routes, session auth and the Blob/FormData upload gotcha ->
  guides/gpx-manager.md "How the manager is wired".
- Trip-switch procedure -> guides/trip-switching.md. CLAUDE.md keeps the
  one rule that matters: never re-add pageconfig.parent to post-form.md.
- Also trimmed the dev-command table and custom-plugin table added in the
  previous commit; both largely restated the Makefile and blueprints.

Fixed the guides being pointed into, so the pointers lead to truth:
- trip-switching.md instructed editing a pageconfig.parent that no longer
  exists -- its whole "two files must be updated together" premise was
  obsolete and would have reintroduced the desync it warned about.
- architecture.md: Grav 2.0.4->2.0.7, Admin2 2.0.10->2.0.12, corrected the
  posting pipeline to show cache-on-save injecting parent before the write,
  added entry-actions to the custom-plugin list.
- japan-korea-2026 -> denmark-2026 across guides/reference (docs/solutions
  keeps its historical references intact -- those are incident records).

Verified: every markdown link resolves, every referenced section heading
exists, and each extracted item was confirmed present in its new home.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 20:55:28 +02:00

3.6 KiB

Managing GPX Files

GPX route files live as media on the active trip page. The map picks them up automatically — any .gpx file in user/pages/01.trips/<active_trip>/ appears on the trip map.


Browser UI — /gpx-manager

The GPX manager at /gpx-manager requires admin login (redirects to login form if not authenticated).

Upload a file

  1. Open /gpx-manager (login required)
  2. Click Choose file → select your .gpx file
  3. Click Upload
  4. The filename is auto-slugified before upload: spaces and special characters become hyphens, everything becomes lowercase.
    • Example: Day 1 — Arrival (Kyoto).gpxday-1-arrival-kyoto.gpx
  5. The file appears in the list immediately

Delete a file

  1. Find the file in the list at /gpx-manager
  2. Click Delete next to it
  3. Confirm — the file is removed from the trip media and will no longer appear on the map

Without the browser UI

Drop the file directly into the trip folder and push:

cp your-route.gpx /path/to/user/pages/01.trips/denmark-2026/
make content-push

make content-push commits and pushes the user/ repo to Gitea, which triggers a production pull via webhook.

Filename tip: slug your filename before dropping it — lowercase, hyphens only:

day-1-kyoto.gpx         ✅
Day 1 Kyoto.gpx         ⚠️  works but slugified on upload; skip this if dropping manually

Filename slugification rules

The browser UI slugifies client-side before upload. Manually placed files are used as-is, so name them cleanly.

Rules applied by the UI:

  • Lowercase everything
  • Replace spaces with hyphens
  • Replace non-alphanumeric characters (except .) with hyphens
  • Collapse multiple consecutive hyphens to one
  • Strip leading/trailing hyphens

Komoot workflow (no API integration yet)

Komoot doesn't offer GPX export via API without authentication. Current workaround:

  1. Open your tour in the Komoot app or website
  2. More → Export → GPX track (available on Komoot Premium; free users get a limited version)
  3. Save the .gpx file to your phone or laptop
  4. Upload via /gpx-manager or drop into the trip folder

Future: a Komoot integration field in the GPX manager (paste tour URL → server fetches GPX) is in the backlog at working/backlog.md.


How files are served

GPX files are registered as a valid media type in user/config/media.yaml, so Grav stores and serves them alongside images. The map template picks them up via:

{% for file in trip_page.media.all %}
  {% if file.filename ends with '.gpx' %}
    {# add to map source list #}
  {% endif %}
{% endfor %}

No manual linking is needed — upload and it appears.


How the manager is wired

Piece Detail
Page user/pages/03.gpx-manager/
Template user/themes/intotheeast/templates/gpx-manager.html.twig
Auth Login plugin, via access.admin.login: true in the page frontmatter — renders the login form when unauthenticated
API Grav API v1 with session cookie auth (session_enabled: true in user/plugins/api/api.yaml)

API calls the page makes:

GET    /api/v1/pages{route}/media              # list
POST   /api/v1/pages{route}/media              # upload (multipart)
DELETE /api/v1/pages{route}/media/{filename}   # delete

Upload gotcha: the selected file is sliced into a plain Blob before FormData.append, so the third argument is always honoured as the filename. Appending the original File lets the browser keep the unslugified name and the slugification is silently ignored.