3

Goal:

I want Username URLs like Facebook, Twitter etc.: example.com/Username

Problem:

URLs like /register etc. can not then be reached if I add

   * @Route("/{user}", name="user_profile")

Of course I could have /user/username, but I need for this case /username.

What is the correct way of implementing this?

One idea was adding an event listener for 404 pages which checks if the URL is example.com/abc and check if the username exists. But that seems like a bad hack.

Short question:

How is it possible to make a route www.example.com/username like Facebook, without conflicts with /register etc. in a professional way?

Patrick Mevzek
  • 10,995
  • 16
  • 38
  • 54
emovere
  • 152
  • 1
  • 13
  • 1
    https://stackoverflow.com/questions/11149526/symfony2-rewrite-rules-htaccess-app-php you should rewrite the url then – Frankich Aug 24 '17 at 14:14

1 Answers1

4

First of all you need to define how you want to deal with collisions of paths like /register, /login, /impressum and usernames colliding with these paths (like "register", "login" and "impressum"). You probably want to have a blacklist of usernames which are not allowed, because they collide with your pre-defined paths.

To solve the actual problem then, you can create a "catchall" route for /{username} (maybe with some restrictions on the {username} part using regex) after all the other routes.

When you request a path in a symfony project, symfony will check the routes in the order they were defined. So if you define your user profile route last (at the bottom of the routing.yml file), it will only be used if all other routes did not match the request. This means, if you have a user with a name like "register", he would not be able to open his profile page, since the /register route for the registration page would match the request first.

In Symfony Standard Edition routing is like this:

app:
    resource: '@AppBundle/Controller/'
    type: annotation

You can't handle route position with annotations, except if you write multiple entries in the routing.yml file. To make sure the user profile route is last, you should probably remove the annotation for this action and create the route by using yml, like this:

app:
    resource: '@AppBundle/Controller/'
    type: annotation

user_profile:
    path: /{user}
    defaults:
        _controller: App:User:profile
Tobias Xy
  • 2,039
  • 18
  • 19
  • Thanks Tobias, that is exactly what I was looking for! One note though, it only worked in dev env, on prod it gave me a 404. After clearing the cache via ./bin/console cache:clear --no-warmup --env=prod; ./bin/console cache:warmup --env=prod it doesn't worked as well. I had to manually clear the cache via rm -rf app/cache/*, then it worked. I'll accept your answer now, again thank you! – emovere Aug 24 '17 at 17:26