Skip to content

feat(images): caption / alt text per image, end-to-end#35

Merged
bigin merged 1 commit into
imanager-2.0from
feature/image-titles
May 3, 2026
Merged

feat(images): caption / alt text per image, end-to-end#35
bigin merged 1 commit into
imanager-2.0from
feature/image-titles

Conversation

@bigin
Copy link
Copy Markdown
Owner

@bigin bigin commented May 3, 2026

Summary

Brings 1.x image-title functional parity onto the 2.0 stack across all
three layers, on top of the iManager files.title column.

Editor — UploadEndpoint:

  • New PATCH method: body {fileId, title, tokenName, tokenValue}
    200 {"status":"ok","title":"..."} on success, 404 unknown id, 400
    missing fileId. Uses the same parseBody() helper as DELETE so it
    works regardless of whether the client posts the body as
    form-urlencoded PATCH or query string.
  • handle() routes PATCH alongside POST and DELETE.

Editor — PagesModule:

  • renderUploadedFileRow emits an inline title input + "save title"
    button per file with data-* attributes the JS handler reads.
  • renderLegacyImageRow takes an index and emits an input named
    legacy_image_titles[<index>] so titles persist with the page save.
    Migrated 1.x entries stay in Item.data.images on purpose (Plan §9:
    no destructive migration).
  • saveAction merges any posted legacy_image_titles[i] back into
    data.images[i].title before re-saving the item.

Editor — filepond-init.js:

  • New click handler on .image-list__title-save: PATCHes the upload
    endpoint, surfaces "saving…", "saved" (auto-clears after 1.5s), or
    "failed" on the row's status span.

Frontend — BasicTheme::headlineImage:

  • Modern attachments now propagate $file->title instead of the
    hardcoded ''. Hero/figure templates already render INFO through
    Sanitizer::markdown so captions support inline markdown (links,
    emphasis), matching the 1.x path.

Test plan

  • POST upload → 200; fileId
  • PATCH title=Captured… → 200 {"status":"ok"}; DB has the title
  • Edit form refetch → title input prefilled with saved value;
    legacy input present (legacy_image_titles[0])
  • POST save-page with legacy_image_titles[0]=… → 302;
    data.images[0].title updated in DB
  • Frontend (cache flushed) → caption rendered in hero
  • Browser: type in caption + save title button → status flashes
    "saved"; reload frontend → caption visible

Brings 1.x image-title functional parity onto the 2.0 stack across
all three layers, on top of the iManager `files.title` column added
in feature/file-title-column.

Editor — UploadEndpoint:
  - New PATCH method: body {fileId, title, tokenName, tokenValue}
    → 200 {"status":"ok","title":"..."} on success, 404 unknown id,
    400 missing fileId. Uses the same parseBody() helper as DELETE
    so the body works whether the client sends form-urlencoded
    PATCH (PHP doesn't populate $_POST for PATCH) or query-string.
  - handle() routes PATCH alongside POST and DELETE.

Editor — PagesModule:
  - renderUploadedFileRow now emits an inline title input + "save
    title" button per file, with data-* attributes (fileId, csrf,
    patch-url) the JS handler reads. Layout switched from sprintf
    to direct concat for readability.
  - renderLegacyImageRow takes an index and emits an input named
    `legacy_image_titles[<index>]` so titles persist with the page
    save action — the migrated 1.x entries stay in Item.data.images
    on purpose (Plan §9: no destructive migration).
  - saveAction merges any posted `legacy_image_titles[i]` value back
    into the matching slot in `data.images[i].title` before
    re-saving the item.

Editor — filepond-init.js:
  - New click handler on `.image-list__title-save`: PATCHes the
    upload endpoint with {fileId, title, csrf}, surfaces "saving…",
    "saved" (auto-clears after 1.5s), or "failed" on the row's
    status span.

Frontend — BasicTheme::headlineImage:
  - Modern attachments now propagate `$file->title` instead of the
    hardcoded ''. Hero/figure templates already wired to render
    'INFO' through Sanitizer::markdown so captions support inline
    markdown (links, emphasis), matching the 1.x render path.

Manual smoke (PHP built-in server, 64×64 PNG fixture):
  POST /editor/api/upload                       → 200; fileId=11
  PATCH /editor/api/upload (title=Captured…)    → 200 {"status":"ok"}
                                                  DB title set
  GET /editor/pages/edit/?page=3                → 200; title-input
                                                  prefilled with
                                                  saved value; legacy
                                                  input named
                                                  legacy_image_titles[0]
  POST save-page (legacy_image_titles[0]=Edited…)
                                                → 302; data.images[0]
                                                  .title updated
  GET /articles/get-started-with-scriptor (cache flushed)
                                                → "Captured by Phase 14
                                                  smoke" in hero caption
@bigin bigin merged commit 42999e8 into imanager-2.0 May 3, 2026
@bigin bigin deleted the feature/image-titles branch May 3, 2026 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant