Skip to content

fix: support decimal numbers in route parameters - #52

Merged
Levdbas merged 4 commits into
Upstatement:masterfrom
thisismyurl:fix/decimal-route-parameters
Jul 7, 2026
Merged

Levdbas merged 4 commits into
Upstatement:masterfrom
thisismyurl:fix/decimal-route-parameters

Conversation

@thisismyurl

Copy link
Copy Markdown
Contributor

Routes with parameters like :version now correctly match decimal numbers such as 1.5.1 and semantic version strings.

Previously, a route like Routes::map('download/:version', callback); would work with /download/release but not /download/1.5.1.

Root Cause

AltoRouter's default parameter pattern excludes dots.

Solution

Define custom 'slug' match type with [a-zA-Z0-9._-]+ for all default route parameters.

Changes

  • Add custom 'slug' match type to AltoRouter in ensure_router()
  • Modify convert_route() to use [slug:param] instead of [:param]
  • Add testRouteWithDecimalParameter() test case
  • Update docblock comments

Backward compatible: Existing routes continue to work unchanged.

Changelog

  • Add custom 'slug' match type to support dots in route parameters
  • Modify parameter conversion to use [slug:param]
  • Add test case for decimal parameters

Testing

  • Added testRouteWithDecimalParameter() test for /download/1.5.1
  • Manual verification confirms routes with decimal numbers now work

Credits

Thanks to @thisismyurl (AI-assisted identification and testing)

Closes #45

Routes with parameters like :version now correctly match decimal numbers such as 1.5.1 and semantic version strings.

Root cause: AltoRouter's default parameter pattern [a-zA-Z0-9_-] excludes dots.

Solution: Define a custom 'slug' match type with pattern [a-zA-Z0-9._-]+ and use it for all default route parameters.

Changes:
- Add custom 'slug' match type to AltoRouter in ensure_router()
- Modify convert_route() to use [slug:param] instead of [:param]
- Add testRouteWithDecimalParameter() test case
- Update docblock comments

Backward compatible: Existing routes continue to work unchanged.
Fixes Upstatement#45

(full disclosure: AI helped me identify the issue and verify my work)
Copilot AI review requested due to automatic review settings June 10, 2026 17:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR adds support for route parameters that include dots (e.g., semantic version strings like 1.5.1) by introducing a custom AltoRouter match type and updating the route conversion logic, along with a regression test.

Changes:

  • Add a custom AltoRouter match type (slug) that allows dots in path parameters.
  • Change convert_route() to convert :param segments into [slug:param].
  • Add a PHPUnit test covering a decimal/semantic-version route parameter.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.

File Description
tests/RoutesTest.php Adds a regression test ensuring routes can match dotted version parameters.
Routes.php Adds a slug match type and updates route conversion to use it by default.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Routes.php Outdated
Comment thread Routes.php Outdated
Comment thread Routes.php
Comment on lines +146 to +147
* Note: Default parameters are converted to [slug:param] to support dots,
* underscores, and hyphens in parameter values (e.g., version numbers like 1.5.1).
Comment thread Routes.php Outdated
Comment thread Routes.php Outdated
Comment thread tests/RoutesTest.php Outdated
Comment thread tests/RoutesTest.php Outdated
@Levdbas

Levdbas commented Jun 11, 2026 •

Copy link
Copy Markdown
Collaborator

Hi @thisismyurl , thank you for this contribution and taking on this long open issue. Copilot did some nitpicking, if you could take a look at those as well, it would be great!

@Levdbas

Levdbas commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

@jarednova , can you take a look at this as well/merge?

@jarednova

Copy link
Copy Markdown
Member

Thanks @thisismyurl ! Totally down w this approach to expand the matching set to include decimals. However, this might inadvertently cause some regressions. The code: [a-zA-Z0-9._-]+ would match all ASCII alphanumerics and a few special chars, but cause a regression with other unicode characters and non-included special chars (i.e. /blog/café). Even though that's not in many standard URL practices, I'm want to make sure we're not breaking someone's site unless is absolutely intended (which I don't think it is).

What if we went from [^/\.]++ => to => [^/]++ — this then permits decimals while still excluding slashes. Any downside to that approach? cc @Levdbas

…ssion

The slug match type used [a-zA-Z0-9._-]++, which fixed version-number params
(1.5.1) but would stop matching Unicode URL segments such as /blog/café. Use
[^/]++ instead — it still allows dots (so version numbers keep working) while
matching any non-slash character, so non-ASCII segments are not regressed.

Adds a Unicode-parameter test alongside the decimal one; it fails against the
allow-list pattern and passes with [^/]++.
@thisismyurl

Copy link
Copy Markdown
Contributor Author

Good call — you're right that [a-zA-Z0-9._-]++ drops Unicode segments like /blog/café, which I hadn't accounted for. [^/]++ is the better shape: it still allows the dots version numbers need, while matching anything that isn't a slash, so non-ASCII segments keep working. Pushed that plus a Unicode test alongside the decimal one (fails against the allow-list, passes with [^/]++). Thanks for catching it before it shipped.

@Levdbas

Levdbas commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Thanks @thisismyurl ! I'm merging this in and we'll ship this in v1

@Levdbas
Levdbas merged commit 8bcfd77 into Upstatement:master Jul 7, 2026
12 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.

Route /download/1.5.1 doesn't work with decimal numbers

4 participants