Skip to content

fix: never emit a double slash in page fullpaths - #263

Open
erdostom-bot wants to merge 1 commit into
maglevhq:mainfrom
erdostom-bot:agent/upstream-double-slash
Open

erdostom-bot wants to merge 1 commit into
maglevhq:mainfrom
erdostom-bot:agent/upstream-double-slash

Conversation

@erdostom-bot

Copy link
Copy Markdown

Problem

Link settings pointing to a Maglev page (or a static page) can render with a double slash, e.g. https://example.com//hello-world.

Maglev::GetPageFullpath#build_fullpath joins [base_url, locale?, path] with '/' without looking at the pieces, and the static page branch of GetPageSections::TransformLinkConcern returns the configured path untouched. In live mode base_url is request.base_url (https://host), so any slash already present on the path side becomes host//path.

When it happens

  • Page paths in the DB: Maglev::PagePath#clean_value strips only one leading/trailing slash and only collapses runs of 3+ slashes, so //hello is stored as /hello and a//b as is. Paths written around validations (imports, update_column, rows predating the cleaner) keep their leading slash.
  • Static pages (config.static_pages): never normalised. /products was returned as /products, products as products (a relative href).
  • base_url with a trailing slash (custom GetBaseUrl, engine mounted at /): base/ + /path.
  • Locale prefix: [host, 'fr', '/path'] gives host/fr//path.

Fix

  • Maglev::GetPageFullpath.join(base_url, *segments): trims leading/trailing slashes from every segment, collapses inner //, keeps the base url's scheme, and always returns a single leading / when there is no base url (/ for the index page). build_fullpath uses it; /index is treated like index.
  • The static page branch uses the same normalisation, so a static page href is now always rooted (/products); absolute urls are left untouched. Small behaviour change for static pages declared without a leading slash, consistent with the page branch.
  • PagePath#clean_value strips every leading/trailing slash and collapses any // run.

Tests

  • spec/services/maglev/get_page_fullpath_spec.rb: leading slash, base url with trailing slash (preview), host base url (live) incl. locale prefix and index, nil base url, static page with /hello-world/, .join edge cases.
  • spec/services/maglev/fetch_sections_content_service_spec.rb: static page link /products/ → /products, absolute static url untouched, anchor href.
  • spec/models/maglev/page_path_spec.rb: cleaning of the stored value.

12 of the new examples fail on main without the fix; all pass with it. RuboCop clean; full non-system suite green locally (postgres).

🤖 Generated with Claude Code

GetPageFullpath#build_fullpath joined the base url, the locale prefix and
the page path blindly, so a path stored with a leading slash
("/hello-world"), a base url ending with a slash or a static page path
declared as "/products" produced hrefs like "https://host//hello-world".

- GetPageFullpath.join strips leading/trailing slashes from every segment,
  collapses inner "//" and always yields a single leading "/" when there
  is no base url (the scheme's "//" is kept).
- The static page branch of TransformLinkConcern uses the same
  normalisation (absolute urls are left untouched).
- PagePath#clean_value now strips every leading/trailing slash (it only
  removed one) and collapses any run of slashes (it only collapsed 3+).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit e668f78)
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