Skip to content

Translate only the literal path of a ~q route - #17

Merged
kipcole9 merged 2 commits into
elixir-localize:mainfrom
rubas:fix/q-query-with-slash
Sep 27, 2026
Merged

kipcole9 merged 2 commits into
elixir-localize:mainfrom
rubas:fix/q-query-with-slash

Conversation

@rubas

@rubas rubas commented Sep 26, 2026

Copy link
Copy Markdown
Contributor

Fixes two bugs in how ~q translates a route, with one change.

Before

Localize.put_locale(:fr)
~q"/users?next=/users"
#=> "/users?next=/users_fr"
~q"/users/#{String.upcase("users")}"
#=> "/users_fr/USERS_FR"

Problem

  • A / inside the query hides the real end of the path. The path stays untranslated, and a query value is translated instead. Literal text after an interpolated query value (?page=#{page}&next=/users) is also translated.
  • String literals inside #{...} code are translated too. A literal that matches a routes msgid (a default value, a map key, a branch result) is silently replaced at compile time.

After

Localize.put_locale(:fr)
~q"/users?next=/users"
#=> "/users_fr?next=/users"
~q"/users?page=#{2}&next=/users"
#=> "/users_fr?page=2&next=/users"
~q"/users/#{String.upcase("users")}"
#=> "/users_fr/USERS"
Details
  • Cause: Localize.Routes.translate_path_now/4 used Macro.prewalk/2, which also visits the code inside each interpolation. translate_segment_parts/4 split each literal on / first and only looked for ? or # in the last piece.
  • Change: translate_path_now/4 walks only the top-level <<>> segments with Enum.map_reduce/3. Each literal is split once at the first ? or #; only the part before it is translated, and every later segment is left as is. Interpolation segments are never walked. ~q, path_for/2 and url_for/2 always pass a <<>> node (normalize_route_ast/1). The now unused catch-all clause of merge_literal_segments/1 is removed (the compiler flagged it).
  • Tests in test/sigil_q_test.exs, both fail on main: sigil_q translates the path but not a path in the query and sigil_q does not translate string literals in interpolated code.
  • Checks: mix test (269 passed), mix compile --warnings-as-errors, mix format --check-formatted, mix credo --strict (only the existing Sigil_q.InterpolationTest name note).

AI disclosure: AI models helped us find this issue, write the change, and review it.

@kipcole9
kipcole9 merged commit 078ea45 into elixir-localize:main Sep 27, 2026
10 checks passed
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.

2 participants