Skip to content

urlFor() / linkTo() fails outbound route generation for namespaced controllers without explicit route names #4695

Open

Description

@mikegrogan

Describe the bug
When using nested controller directories inside a .namespace() block with dynamic [action] routing, inbound routing works as expected, but outbound link generation (urlFor / linkTo) fails to parse the controller package context correctly.

Instead of generating clean forward-slash delimited paths (e.g., /admin/users/show/1), CFWheels produces malformed URLs containing hyphenated slugs (e.g., /admin.-users/show/1) or double-encoded entities (e.g., %2-f) unless an explicit name="" parameter is assigned to the route.

To Reproduce
Steps to reproduce the behavior:

  1. Define an unnamed generic route inside a namespace (config/routes.cfm):
.namespace("admin")
    .get(pattern="users/[action]/[key]", to="users##[action]")
.end()
  1. Place a controller in the nested package directory (controllers/admin/users.cfc):
component extends="Controller" {
    public function index() {}
    public function show() {}
}
  1. Use a linkto()
<!--- Standard helper call from within the namespaced view --->
#linkTo(text="View User", action="show", key=1)#

<!--- Passing full controller path explicitly --->
#linkTo(text="View User", controller="admin/users", action="show", key=1)#

Expected behavior
Both helper calls should generate:https://example.com/admin/users/show/1

Actual Behavior
Standard call: Produces a hyphenated package slug:
https://example.com/admin.-users/show/1

Slash-separated controller call: URL-encodes the slash into a hyphen entity:
https://example.com/admin%2-fusers/show/1

Workaround
Adding an explicit name attribute to the generic route pattern inside routes.cfm bypasses the internal package-guessing logic and allows outbound link generation to resolve cleanly:

.namespace("admin")
    // Explicitly naming the generic route resolves the issue
    .get(name="UsersKey", pattern="users/[action]/[key]", to="users##[action]")
.end()
<!--- Works correctly with explicit route name. Note that the action="show" 
is just a regular variable here like key.  It's not the internal wheels action. 
As far as I can tell at least. --->
#linkTo(route="adminUsersKey", action="show", key=1)#

Additional context

  • Wheels 4.0.5
  • Adobe Coldfusion 2023

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions