Skip to content

Command Line Tools

wheels generate route

Generate route definitions for your Wheels application’s /config/routes.cfm file.

Terminal window
wheels generate route [objectname]
#can also be used as:
wheels g route [objectname]
# HTTP method routes
wheels generate route --get="pattern,controller##action"
wheels generate route --post="pattern,controller##action"
wheels generate route --put="pattern,controller##action"
wheels generate route --patch="pattern,controller##action"
wheels generate route --delete="pattern,controller##action"
# Root route
wheels generate route --root="controller##action"
# Resources route (explicit)
wheels generate route --resources=true [objectname]

The wheels generate route command helps you create route definitions in your Wheels application’s /config/routes.cfm file. It supports individual HTTP method routes, RESTful resource routes, and root routes.

IMPORTANT: All HTTP method parameters must use the equals syntax: --get="pattern,handler" not --get pattern,handler

CommandBox supports multiple parameter formats:

  • Named parameters: name=value (e.g., objectname=products, get="pattern,handler")
  • Flag parameters: --flag equals flag=true (e.g., --resources equals resources=true)
  • Flag with value: --flag=value equals flag=value (e.g., --get="pattern,handler")

Note: Flag syntax (--flag) avoids positional/named parameter conflicts and is recommended for boolean options.

ArgumentDescriptionDefault
objectnameThe name of the resource for resources routeOptional (required for resources routes)
OptionDescriptionExampleDefault
--getCreate a GET route with pattern,handler format--get="products/sale,products##sale"
--postCreate a POST route with pattern,handler format--post="contact,contact##send"
--putCreate a PUT route with pattern,handler format--put="users/[key],users##update"
--patchCreate a PATCH route with pattern,handler format--patch="profiles,profiles##update"
--deleteCreate a DELETE route with pattern,handler format--delete="sessions,sessions##destroy"
--resourcesCreate a resources route (use with objectname)--resources=truefalse
--rootCreate a root route with handler--root="pages##home"
Terminal window
wheels generate route products

Generates in /config/routes.cfm:

.resources("products")

This creates all standard RESTful routes:

  • GET /products (index)
  • GET /products/new (new)
  • POST /products (create)
  • GET /products/[key] (show)
  • GET /products/[key]/edit (edit)
  • PUT/PATCH /products/[key] (update)
  • DELETE /products/[key] (delete)
Terminal window
wheels generate route --get="products/sale,products##sale"

Generates:

.get(pattern="products/sale", to="products##sale")
Terminal window
wheels generate route --post="api/users,api.users##create"

Generates:

.post(pattern="api/users", to="api.users##create")
Terminal window
wheels generate route --put="users/[key]/activate,users##activate"

Generates:

.put(pattern="users/[key]/activate", to="users##activate")
Terminal window
wheels generate route --delete="sessions,sessions##destroy"

Generates:

.delete(pattern="sessions", to="sessions##destroy")
Terminal window
wheels generate route --root="pages##home"

Generates:

.root(to="pages##home", method="get")
Terminal window
wheels generate route --resources=true users

Generates:

.resources("users")

Routes support dynamic segments using [key] notation:

Terminal window
wheels generate route --get="users/[key]/profile,users##profile"

Generates:

.get(pattern="users/[key]/profile", to="users##profile")

The [key] parameter will be available as params.key in your controller.

You can use any parameter name:

Terminal window
wheels generate route --get="posts/[year]/[month],posts##archive"

Generates:

.get(pattern="posts/[year]/[month]", to="posts##archive")

Parameters will be available as params.year and params.month in your controller.

If you omit the handler, the route will use standard controller/action mapping:

Terminal window
wheels generate route --get="products/search"

Generates:

.get(pattern="products/search")

This will map to the search action in the products controller.

All routes are added to /config/routes.cfm at the CLI marker position:

<cfscript>
mapper()
.resources("products") // Existing routes
.get(pattern="about", to="pages#about") // Existing routes
// CLI-Appends-Here // CLI adds new routes here
.wildcard() // Wildcard should stay last
.root(to="home#index") // Root route
.end();
</cfscript>

The command automatically places new routes at the correct position before the wildcard route. Routes are processed in order, so specific routes must come before general ones.

Resource routes automatically create URL helpers:

<!--- For resources("products") --->
#linkTo(route="products", text="All Products")# <!-- /products -->
#linkTo(route="product", key=123, text="View")# <!-- /products/123 -->
#linkTo(route="newProduct", text="Add Product")# <!-- /products/new -->
#linkTo(route="editProduct", key=123, text="Edit")# <!-- /products/123/edit -->
#urlFor(route="products")# <!-- /products -->
#urlFor(route="product", key=123)# <!-- /products/123 -->

For custom routes, you’ll need to manually create route names in your routes.cfm:

<!--- Add name parameter manually in routes.cfm --->
.get(name="productSale", pattern="products/sale", to="products##sale")
<!--- Then use in views --->
#linkTo(route="productSale", text="Special Sale")#

Building on CommandBox’s parameter syntax, Wheels route generation supports:

Terminal window
wheels generate route --get="products/sale,products##sale"
wheels generate route --post="contact/send,contact##send"
wheels generate route --resources=true --objectname=users
wheels generate route --root="pages##home"
Terminal window
wheels generate route products # objectname (resources route)
wheels g route users # Short alias with objectname
Terminal window
wheels generate route users --resources=true
wheels generate route --objectname=products --resources=true
  • Format: --method="pattern,handler" or --method="pattern"
  • Methods: get, post, put, patch, delete
  • Separator: Comma (,) between pattern and handler
  • Quotes: Always use quotes around the value
  • Handler Format: controller##action (double hash required in CFML)
  • Format: --resources=true objectname or objectname --resources=true
  • Boolean: Must be explicit true or false
  • Objectname: Required when using resources flag
  • Format: --root="controller##action"
  • Handler: Required controller and action
  • Quotes: Always use quotes
Terminal window
# GET route with handler
wheels generate route --get="api/users,api##index"
# POST route with handler
wheels generate route --post="users/login,sessions##create"
# PUT route with handler
wheels generate route --put="profiles/[key],profiles##update"
Terminal window
# Pattern-only routes (uses convention)
wheels generate route --get="products/search"
wheels generate route --post="newsletter/signup"
Terminal window
# Resources flag (explicit true/false)
wheels generate route --resources=true products
wheels generate route --resources=false # Invalid - needs objectname
Terminal window
# Objectname with resources flag
wheels generate route products --resources=true
wheels generate route --resources=true users
# Multiple routes in sequence
wheels generate route --get="login,sessions##new"
wheels generate route --post="login,sessions##create"
wheels generate route --delete="logout,sessions##destroy"

Missing equals sign:

Terminal window
wheels generate route --get products/sale,products##sale

Missing quotes:

Terminal window
wheels generate route --get=products/sale,products##sale

Single hash instead of double:

Terminal window
wheels generate route --get="products/sale,products#sale"

Missing objectname with resources:

Terminal window
wheels generate route --resources=true # No objectname

Correct formats:

Terminal window
wheels generate route --get="products/sale,products##sale"
wheels generate route products --resources
wheels generate route --root="pages##home"
wheels generate route users # Positional objectname
Terminal window
# Single parameter
wheels generate route --get="users/[key],users##show"
# Multiple parameters
wheels generate route --get="posts/[year]/[month],posts##archive"
# Optional parameters (configure manually in routes.cfm)
wheels generate route --get="blog/[category]" # Add [category?] manually
Terminal window
# RESTful API endpoints
wheels generate route --get="api/v1/users,api.v1.users##index"
wheels generate route --post="api/v1/users,api.v1.users##create"
wheels generate route --put="api/v1/users/[key],api.v1.users##update"
wheels generate route --delete="api/v1/users/[key],api.v1.users##destroy"
Terminal window
# Admin controllers
wheels generate route --get="admin/dashboard,admin.dashboard##index"
wheels generate route --get="admin/users,admin.users##index"
# Module-based controllers
wheels generate route --get="shop/products,shop.products##index"
wheels generate route --post="shop/checkout,shop.checkout##process"
  1. Quoted Parameters: Preserve spaces and special characters
  2. Equals Processing: Splits parameter name from value
  3. Boolean Conversion: Converts “true”/“false” strings to boolean values
  4. Array Processing: CommandBox processes space-separated values as arrays
  1. reconstructArgs(): Processes CommandBox parameter format
  2. Validation: Checks required parameters are present
  3. Route Generation: Formats parameters for Wheels router syntax
  4. File Injection: Places routes at correct position in routes.cfm

The command looks for // CLI-Appends-Here comment to place new routes. If not found, it tries different indentation levels:

  1. // CLI-Appends-Here (3 tabs)
  2. // CLI-Appends-Here (2 tabs)
  3. // CLI-Appends-Here (1 tab)
  4. // CLI-Appends-Here (no tabs)

After using the CLI, you may want to reorganize routes manually:

<cfscript>
mapper()
// Public pages first
.get(pattern="about", to="pages##about")
.get(pattern="contact", to="contact##index")
// Resources grouped together
.resources("products")
.resources("users")
// Authentication routes
.get(pattern="login", to="sessions##new")
.post(pattern="login", to="sessions##create")
// CLI generated routes will appear here
// CLI-Appends-Here
.wildcard() // Always keep wildcard last
.root(to="home##index", method="get")
.end();
</cfscript>
  1. Use equals syntax: Always use --get="pattern,handler" format
  2. Resources for CRUD: Use resources route for full CRUD operations
  3. Custom routes for special actions: Use HTTP method routes for non-CRUD actions
  4. Check route order: Specific routes before general ones
  5. Test after generation: Visit URLs to ensure routes work
  6. Reload application: Use ?reload=true after route changes

Issue: "Missing argument" errors when using HTTP method parameters

Incorrect:

Terminal window
wheels generate route --get products/sale,products##sale # Missing =
wheels generate route --post contact send # Missing quotes and =

Correct:

Terminal window
wheels generate route --get="products/sale,products##sale" # With = and quotes
wheels generate route --post="contact,sessions##create" # Proper format

Solution: Always use equals syntax with quotes for HTTP method parameters.

Issue: Template compilation errors with single hash (#) in handlers

Incorrect:

Terminal window
wheels generate route --get="users,users#show" # Single # causes CFML errors

Correct:

Terminal window
wheels generate route --get="users,users##show" # Double ## for CFML escaping

Solution: Always use double hash (##) in controller##action handlers.

Issue: Generated routes don’t respond or show 404 errors

Possible Causes:

  • Application not reloaded after route changes
  • Route order conflicts (specific routes after wildcard)
  • Controller or action doesn’t exist

Solutions:

Terminal window
# 1. Always reload after route changes
http://localhost:8080/?reload=true
# 2. Check route order in routes.cfm
# Ensure wildcard() comes AFTER specific routes
# 3. Verify controller exists
# For route: --get="products,products##sale"
# Need: /app/controllers/Products.cfc with sale() function

Issue: Complex patterns not parsed correctly

Problematic:

Terminal window
# Spaces in patterns without quotes
wheels generate route --get=api/v1/users,api##index
# Special characters not escaped
wheels generate route --get="api-users,api#index"

Solutions:

Terminal window
# Always quote complex patterns
wheels generate route --get="api/v1/users,api##index"
# Use proper CFML escaping
wheels generate route --get="api-users,api##index"

Issue: Resources flag not working or missing objectname

Common Mistakes:

Terminal window
wheels generate route --resources=true # Missing objectname
wheels generate route --resources products # Missing =true
wheels generate route products --resource # Wrong flag name

Correct Usage:

Terminal window
wheels generate route --resources=true products # Explicit flag with objectname
wheels generate route products --resources=true # Alternative order
wheels generate route products # Default resources (implicit)

Issue: Routes added in wrong location or break existing routes

Common Problems:

  • CLI marker // CLI-Appends-Here not found
  • Routes added after wildcard route
  • Malformed routes.cfm syntax

Solutions:

<!-- Ensure routes.cfm has proper structure -->
<cfscript>
mapper()
// Existing routes
.resources("products")
// CLI marker for new routes
// CLI-Appends-Here
// Wildcard MUST be last
.wildcard()
// Root route
.root(to="home##index", method="get")
.end(); // Don't forget .end()!
</cfscript>

Before generating routes, verify:

Terminal window
# 1. Check current directory is Wheels app root
ls config/routes.cfm # Should exist
# 2. Verify routes.cfm has CLI marker
grep "CLI-Appends-Here" config/routes.cfm # Should find marker
# 3. Check routes.cfm syntax is valid
# Look for proper mapper() and .end() structure

After generating routes, always:

Terminal window
# 1. Reload application
http://localhost:8080/?reload=true
# 2. Test route in browser
http://localhost:8080/your-new-route
# 3. Check debug footer for route information
# Look for your new route in the Routes section
Terminal window
# Test different HTTP methods
curl -X GET http://localhost:8080/api/users
curl -X POST http://localhost:8080/api/users -d "name=test"
curl -X PUT http://localhost:8080/api/users/1 -d "name=updated"
curl -X DELETE http://localhost:8080/api/users/1

“Please provide either an objectname for a resources route or specify a route type”

  • Cause: No parameters provided to command
  • Solution: Provide either objectname or HTTP method parameter

“key [TYPE] doesn’t exist”

  • Cause: Internal processing error (rare)
  • Solution: Try simpler route first, then add complexity

“Template compilation error”

  • Cause: Single hash (#) in generated route
  • Solution: Check for double hash (##) in all handlers

“Route not found” (404 errors)

  • Cause: Route not added or application not reloaded
  • Solution: Check routes.cfm and reload application
Terminal window
# Always use consistent formatting
wheels generate route --get="pattern,handler" # ✅ Consistent
wheels generate route --get pattern,handler # ❌ Inconsistent
Terminal window
# Plan route structure before generating
# 1. Resources routes first
wheels generate route products
wheels generate route users
# 2. Custom routes second
wheels generate route --get="search,search##index"
wheels generate route --post="contact,contact##send"
# 3. API routes with namespace pattern
wheels generate route --get="api/products,api.products##index"
Terminal window
# Generate one route at a time
wheels generate route --get="test,test##index"
# Test it works
curl http://localhost:8080/test
# Then generate next route
Terminal window
# Document custom routes in routes.cfm
.get(name="productSearch", pattern="products/search", to="products##search")
// Custom search endpoint for products - returns JSON

If you encounter issues not covered here:

  1. Check the debug footer: Shows all registered routes
  2. Verify controller exists: Match route handler to actual controller/action
  3. Test with simple routes first: Basic patterns before complex ones
  4. Check Wheels routing guide: For advanced routing features
  5. Reload frequently: Always reload after route changes