Skip to content

LPB: Allow image upload in metadata section#355

Open
jsandland wants to merge 176 commits into
stagefrom
lpb-image-upload-metadata
Open

LPB: Allow image upload in metadata section#355
jsandland wants to merge 176 commits into
stagefrom
lpb-image-upload-metadata

Conversation

@jsandland
Copy link
Copy Markdown

Add your specific features or fixes:

  • LPB Metadata: Required Social share / OG image field with file picker, preview, replace, and remove (same image-dropzone pattern as other images).
  • Save / templating: Uploaded asset is written into page output via the {{social-share-image}} placeholder (absolute content URL); applyTemplateData treats it as a plain URL (not wrapped in ) so it can drive og:image / page-metadata.
  • Errors: Clearer toasts for path/file name limits and server rejection on image (and PDF) uploads.

Resolves: MWPW-193613

Test URLs:
Before: https://main--da-bacom--adobecom.aem.live/?martech=off
After: https://lpb-image-upload-metadata--da-bacom--adobecom.aem.live/?martech=off

LPB:
Before: https://da.live/app/adobecom/da-bacom/tools/generator/landing-page
After: https://da.live/app/adobecom/da-bacom/tools/generator/landing-page?ref=lpb-image-upload-metadata

auniverseaway and others added 30 commits November 5, 2024 13:56
* Rollout a page without a loc project
* Rollout to langstore/en
* Rollout to locales from langstore/XYZ
* Ability to de-select regions
* Can link out to pages before rollout
Upgrade da-bacom to hlx5
Attempting to move back to file-based configs.
…ilities. Confirmed that all npm scripts work as expected (#7)
[Release] Stage to Main
JasonHowellSlavin and others added 10 commits April 14, 2026 16:08
The milolibs query param was interpolated directly into template
literals used for dynamic import()s, letting an attacker point module
loading at an arbitrary origin and execute JS in the page context.

Add a strict whitelist (^[a-zA-Z0-9_-]+$) and throw on invalid input
in head.html and scripts/scripts.js.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* Placements for ctas

* Removing cta placement code

* 104px as requested
* Small changes for readability

* Small changes for readability
@aem-code-sync
Copy link
Copy Markdown

aem-code-sync Bot commented May 4, 2026

Page Scores Audits Google
📱 /?martech=off PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI
🖥️ /?martech=off PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI

Brandon32 and others added 8 commits May 7, 2026 09:54
…Bacom space (#164)

* Adding Stream app

* Update figma.html

* Fix missing newline at end of daUtils.js

Add newline at the end of daUtils.js file
* feat: add quickedit

* Update quick-edit.js

Co-authored-by: Brandon Marshall <kem5brandon@gmail.com>

* Update quick-edit.js

---------

Co-authored-by: Brandon Marshall <kem5brandon@gmail.com>
* add asset headline field to LPB for gated content types

* add nala e2e tests

* ensure h2 populates above pdf
* don't require marquee image or body description for Ungated Guide

* add LPB_GATED and LPB_CONTENT_TYPE constants

* adds unit tests

* replace console.error with lana.log in daUtils
@jsandland jsandland force-pushed the lpb-image-upload-metadata branch from 6ea51ce to 2569940 Compare May 11, 2026 18:42
jsandland and others added 7 commits May 12, 2026 11:14
* Add Landing Page Builder audit log

Track every page built with the landing page builder in a shared DA sheet
so campaign pages (URL, publisher, publish date, content type, LPB version)
are auditable for PMs without manual bookkeeping.

- tools/generator/lpb-log.js: shared module with appendLogRow (realtime
  upsert that preserves original publishedAt) and rebuildLog (uses DA's
  crawl utility to walk /resources, extracts the hidden page-builder marker
  table, merges with existing rows, and soft-deletes pages that no longer
  carry the marker)
- tools/generator/landing-page.js: append a log row after a successful
  save + preview; publisher resolved via context.user then JWT fallback
- tools/lpb-log/: standalone DA viewer app with sortable table, active/
  removed/all tabs, and a Rebuild-from-scan button with live progress
- Registered in sidekick config as "Landing Page Log"
- 22 unit tests covering marker extraction, merge, soft-delete, and
  realtime upsert behavior

Sheet location: /tools/page-builder/landing-page/data/lpb-log

Made-with: Cursor

* adds csv export

* lpb-log: cache-bust viewer assets so CSV button ships to browsers

ES module + CSS on aem.page are cached aggressively; query params on
script/link force a fresh fetch after deploy. Slightly raise disabled
button opacity so Download CSV stays visible when the list is empty.

Made-with: Cursor

* resolve unknown publisher in data

* capture last published by

* remove Status and move last seen to header

* force browser cache bust

* resolve publisher via admin.da.live source, versionlist, and Helix status

* remove public json and open spreadsheet from top of app

* improve logging

* refactor to avoid use of custom escapeHTML util

* add comments to catch blocks for session storage

* add locale-aware scanning and address review findings

- extract LOCALES to scripts/locales.js to avoid scripts.js DOM side effects in paths-config.js
- wire getScanRoots() into scanResources for parallel multi-locale crawling
- await logPublish() so lana catches internal rejections
- fix subtitle copy: "on publish" → "on Save & Preview"
- update crawl mock to filter by path and loosen rebuildLog test assertion

* add publish state distinction and fix scan progress UX

- add fetchPublishState via Helix live API to distinguish published vs preview-only pages
- wire publishState into appendLogRow and rebuildLog
- rename logPublish → logPreview to reflect actual action
- update viewer tabs to Published / Unpublished / Deleted / All
- add Publish State column, rename publishedAt label to First Previewed
- replace per-file scan progress with per-root counter (Scanning root X of 93)

* add authoring link to viewer and remove LPB version column

- add Author link per row opening the DA editor for that document
- remove LPB version from table and CSV — not actionable enough to surface

* move authoring link to its own column in the viewer

- Author column replaces inline link in Page URL cell
- CSV export writes the full DA edit URL in the Author column

* fix scan finding 0 pages and default to All tab

- make scanResources callback synchronous so crawl utility doesn't
  silently drop async I/O (callbacks are fire-and-forget in da.live's
  crawl); collect HTML paths first, then fetch+filter in a second pass
- change default viewer tab from Published to All so existing log data
  is visible immediately without requiring a rebuild

* fix marker detection for DA authoring table format and throttle source fetches

- extractMarker now handles both formats: Franklin-processed divs with CSS
  classes (generated by addHiddenTable) and DA's authoring table format where
  the block name appears as text in the first cell ("table (hide-block, page-builder)")
- process HTML paths in throttle-sized chunks (default 10) instead of all at
  once to avoid overwhelming the DA source API and silently dropping pages
- add console.log for pages where source is unavailable or no marker found
- add test for DA authoring table format detection

* show completed root path in scan progress

- pass completedRoot from scanResources onProgress callback
- viewer displays "Scanned /jp/resources (44 of 93 roots) — 28 pages found"
  so each locale root is visible as it completes

* fix publish state check — use AEM live HEAD instead of Helix admin status API

- admin.hlx.page/status CORS-blocks requests from branch preview origins;
  replace with a HEAD request to the public AEM live CDN which allows CORS
  from any origin and is semantically correct (200 = published, non-200 = not)
- update test to stub globalThis.fetch and assert the aem.live URL is called

* crawl locale roots sequentially to prevent ERR_INSUFFICIENT_RESOURCES

parallel crawls each spawn many admin.da.live/list requests; with 93 roots
running at once the browser runs out of connections — crawl one root at a time
so at most throttle (10) list requests are in flight at any moment

* fix publish state detection: use Helix admin API via daFetch, scoped to en-US /resources

- Replace aem.live HEAD approach (soft-404 returns 200 for all pages) with
  daFetch to admin.hlx.page/status — works from da.live origin
- Add fetchSourceDoc to fetch DA source HTML without a Helix fallback call,
  eliminating the CORS noise that appeared during scan
- Revert scanResources to en-US /resources only — multi-locale crawl (93 roots,
  32 995 pages) was completely untenable; locale support is a separate task
- Remove [lpb-scan] no-marker console.log (printed for every non-LPB page)
- Add [lpb-status] console.log so the full Helix status payload is visible
  while diagnosing published/unpublished classification
- Update publishState test to use daFetch mock instead of globalThis.fetch stub

* improve scan progress UX: per-chunk updates and animated ellipsis button

- scanResources now fires onProgress after each source-fetch chunk so the UI
  updates throughout the slow fetch phase, not just once after the crawl
- Viewer shows two-phase messages: "Crawled /resources — N pages to check"
  then "Checking: X / N — K LPB pages found" (updates every 10 pages)
- Button text changes to "Scanning" with a CSS animated ellipsis (::after)
  so it never looks statically done while requests are still in flight

* revert locales.js extraction — inline LOCALES back into scripts.js

The locale data was split out to avoid scripts.js side effects when
paths-config.js imported it for getScanRoots(). Since the scan is now
scoped to en-US /resources only, getScanRoots() is dead code. Removing
it eliminates the dependency, making locales.js unnecessary.

* restore scripts.js to its pre-branch state

* simplify scan UX: static Scanning... button, rename Checking to Scanning in progress

* remove lpb-status console log and unnecessary preview POST after save

* re-enable multi-locale scan across all 93 /resources roots

scripts/locales.js exports LOCALE_PREFIXES (keys only, no side effects) so
paths-config.js can build scan roots without importing scripts.js.
scripts/scripts.js is unchanged from stage.

* move CONFIG.locales to scripts/locales.js as the single source of truth

Both scripts.js and paths-config.js (via getScanRoots) now import from
locales.js, eliminating the risk of the two objects drifting out of sync.

* live scan counter and spinner on progress bar

Crawl phase now shows 'Scanning: root N of 93 — X pages indexed' so the
counter increments visibly across all roots. Source check phase already
shows 'Scanning: X / Y — N LPB pages found'. CSS spinner added to the
progress bar so there is always a visual working indicator between updates.

* remove spinner from progress bar

* restore spinner on progress bar

* show current locale root in scan progress

* pipeline crawl and source-check phases for faster scan

- crawl 10 roots at a time (was sequential) and immediately start
  source-checking discovered paths while the next batch crawls
- source-check in chunks of 60 (was 10) for higher parallelism
- viewer progress combines both phases into one line during overlap

* reduce crawl batch to 3 to avoid ERR_INSUFFICIENT_RESOURCES

10 concurrent crawls * internal throttle of 10 = 100 concurrent DA list
requests, which overflows the browser connection pool. 3 is the proven
safe ceiling (30 concurrent).

* restore locale root in crawl progress message

* fix log gaps and CSV export: log on page success regardless of PDF, export all tabs with full URLs

* split previewedAt and publishedAt into distinct fields sourced from Helix

preview.lastModified → previewedAt, live.lastModified → publishedAt; rebuild
no longer falls back to now so timestamps reflect actual Helix state; sort
falls back from publishedAt to previewedAt so unpublished pages stay visible

* use marker publishedBy as sole publisher source, drop last-modified-by machinery

DA last-modified-by header reflects who last touched the doc, not who published
via LPB. Remove getSourceWithMeta, lastModifiedByFromSourceResponse, and the
versionlist/Helix fallback fetches that were adding latency to every page load.

* never fall back to prev publisher on rescan; unknown if marker has no publishedBy

prev?.publisher could carry a wrong value set by the old last-modified-by code,
causing stale incorrect names to persist through every subsequent rescan.

* restore DA last-modified-by as publisher fallback when marker has no valid publisher

resolvePublisher was writing 'unknown' into the marker for all pages because IMS
tokens are opaque and the DA SDK doesn't surface user context. Treat a marker
publishedBy of 'unknown' (or absent) the same as missing and fall back to the
x-da-last-modified-by header, which correctly reflects who saved the page via LPB.

* fall back to DA versionlist for publisher when marker has none

The marker's publishedBy is 'unknown' (resolvePublisher can't decode opaque IMS
tokens) or absent (pages saved before April 24). Use the DA versionlist API as a
fallback — it records the actual user per version — so the publisher column shows
real emails on rebuild. Marker value still wins when valid.

* fetch IMS profile when DA pre-seeds initIms with token only

DA calls setImsDetails(token) before the tool loads, so initIms() returns
{ accessToken } with no email or profile. Fall back to window.adobeIMS.getProfile()
which DA already initialized, so resolvePublisher gets a real email instead of
decoding an opaque token and writing 'unknown' to the marker.

* replace publisher with previewedBy + publishedBy sourced from Helix status API

* filter nala URLs from log view; disable scan and warn when not signed in

* pulse signed-out warning to draw attention

* improve signed-out warning copy
* moves locales back to scripts.js

* delete locales.js

* inline LOCALES into paths-config.js, remove scripts.js export
Co-authored-by: denli <denli@adobe.com>
Enable guest accounts and token refresh, allow guest in check_token API
parameters, and reload the page when the token expires so sessions recover
cleanly.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Dennis Li <34138453+Dli3@users.noreply.github.com>
Resolve conflict in tools/generator/landing-page.js: keep sanitizeFileName
import from our branch and add appendLogRow/resolvePublisher from stage.
Keep LPB_VERSION 1.1.1 from our branch.
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.