Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
custom routing (username in URL)
  • Hi, i have a little problem using custom advanced routes. Say my app has a user fred. I wanna have URL's like example.com/fred which routes to "users/index" (the user's profile)
    For this i have a custom route in config/routes.php like this: ':username' => 'users/index', // see http://docs.fuelphp.com/general/routing.html#/advanced What if i would like to have a url like this:
    example.com/fred/something_else ':username/:something_else' => 'users/anotheraction', Problem is now that any other url like example.com/accounts/signup doesnt work
    anymore if i dont put an entry before ':username/:something_else' in routes.php like: 'accounts/signup' => 'accounts/signup' as an example: soundcloud is able to do this: soundcloud.com/[username]/[trackname] any ideas how i can do this in a clean way?
  • Hey,
    sorry for writing so late.
    My solution is now something like dynamic routing:
    first i set all my custom routes and also one route for every controller like: (routes.php) $routes = array(
    custom => public/custom,
    accounts => accounts/index // default for every controller
    ...
    ); After that i check the first segment in the uri via isset($routes[$segment1]) and if this is not the case i add: $routes = 'users/index/$1'; return $routes; Problem is that every time a new route or a new controller gets added, the developer must first check if a
    username with this name already exists and if so, give that controller another name and add one default route.
    Also in the signup process i check routes and controller names, so that no username is created with name e.g. "accounts". if you want to change your github username to login, it says "login is a reserved word", because they have github.com/login already... so maybe there's a bettter solution, but i think this one is ok.
  • If you need logic to determine which action method in your controller needs to be called, you should implement the router() method in the controller. It will capture all calls to the controller, and has access to the segments in the URL and the method requested. You can then use whatever logic needed to determine if the method requested is a user, and if not, check if a method by that name exists. If so, call it, if not, bail out with an HttpNotFoundException.
  • I don't think that fuelphp supports routing order like e.g. Rails does, but the easiest way to solve your problem is to prefix the route with /user but it would be nice though if fuelphp did support route ordering so we could define /some/other/action => 'base/action'
    /some/action => 'base/index
    /some/:parametric_action => 'base/advanced_action' so the router would fire the first route that fits.
  • It does. Routes are processed in the order that they are defined. You need to define the correct ones in the proper order. If you define one with a variable, how would the framework know that you don't want it to match certain URL's? The routing engine doesn't know the concept of 'username', so how would it know 'accounts' is not a username?
  • Thanks for the quick replies! I know i could prefix users/:username and users/:username/:some but it would be nice if its just /[username] ... Also, of course i have routes in right order. for example i have 'about' => 'public/about', ':username/:some' => 'users/some' // -> second to last rule in routes.php
    ':username' => 'users/index' // -> last rule in routes.php but my problem still is that if i add any new action, say 'accounts/edit', i would also have to add a rule /before/ my username routes,
    and i think that's a smelly thing...
  • I understand what you want. I just want to know how you think you're going to tell the routing engine what a username is, how to determine if one is valid, and continue processing routes if it's not valid. You could work around it by using a closure as a route target. Have that do a lookup of the parameter, and if not a username, return an HMVC call for the controller/method combo, with routing disabled to avoid a loop. Simplest however is to use the router() method in your Users controller. Have it check if the action requested is a defined action. If so, call it, if not, assume it's a username. Problem solved.
  • Thanks again, that sounds pretty simple, but i cannot get it to work... currently my very last rule is: '(:any)' => 'users/index/$1', what do you mean by check for defined action ? and how to call it ? in users/router($method, $params) {
    \Request::forge(($path), false)->execute(); ? or: if (method_exists($this, $method)) {
    call_user_func_array(array($this, $method), $params);
    } problem still is that for example accounts/login would then be routed to users/index if i dont add accounts/login => accounts/login ...
    and that's what i try to avoid is there a way to define a rule like accounts/* => accounts/* ? so i would only have to add one rule for every new controller before my :any-rule ... sorry maybe i forgot something ...
  • If you have a design where a URI like "users/<something>" has to route to different controllers, and "<something>" may or may not indicate a method name, there's something wrong with your design, and you're making it an awful lot more complicated than it have to be. No matter what you do, somewhere in your code you'll have to tell the framework what a specific URI translates too. If not in a route, then in a controllers router() method or in an inline route (a closure). Either way, you'll have to add code when something changes. Unfortunately, we haven't gotten to the point that the framework is clairvoyant and can guess what a certain URI means to you. The alternative, just try all posibilities until you have a hit, is very inefficient and indicates a poor design. FuelPHP will never have a feature that will do that.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion