ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

looking for best way to implement unique urls

November 27, 2007 10:42am

Subscribe [7]
  • #1 / Nov 27, 2007 10:42am

    tokyotoejam

    4 posts

    I’ll keep this simple
    I am building a social network with CI.
    I want the members to have urls like http://www.mysite.com/username

    Username would be whatever username the member signedup up with.

    What the best way to tell the CI router that http://www.mysite.com/username needs to goto http://www.mysite.com/member/username. In other words, keep CI from thinking that username is a controller.

  • #2 / Nov 27, 2007 12:31pm

    Sarfaraz Momin

    233 posts

    I would not give you a code example rather would explain you how you can achieve this. Please read the user guide - Routing section which will help you with routing. This will help you make clean URLs. For better support you can search the forum or ask for help here.

    Secondly read controllers - _remap function which will help you execute any code without going to any function. What I mean is if you have a controller named ‘Front’ and within that you have a function named ‘First’ and if you call the url as ‘www.domain.com/front/first’ then it will get you the first function but if you have another function named _remap irrespective of which function is called within that controller, _remap function will be called and you can execute a code to check if the segment of the URL is a username or not. If it is a username then you can redirect it to the respective function within that controller by using

    $this->members();

    else you can redirect them appropriately to other functions.

    I hope it makes sense.

    P.S: I could have easily provided the code but would like you to write one because in the process you might end up writing much better code then what I did and that might help the community with some similar queries in future. Still if you have any doubts please let me know I would provide you the code.

    Good Day !!!

  • #3 / Nov 27, 2007 12:39pm

    Michael Wales's avatar

    Michael Wales

    2070 posts

    I’d just like to expound on what Sarfraz said a bit. You can use Routing (like he said - check out the documentation) to route all requests for ‘member/username’ to a specific function, thus bypassing the need for the _remap function (although the _remap function may be easier to understand).

  • #4 / Nov 27, 2007 2:52pm

    tokyotoejam

    4 posts

    Thanks guys for the quick and informative responses. I will look into these and let you know which way I ended up solving this. 😊

  • #5 / Nov 27, 2007 9:12pm

    indocoder

    23 posts

    I use the same approach. Instead using it for user, I using it on my cms to gain something like index.php/page/title_of_the_page

  • #6 / Nov 29, 2007 12:11am

    coolfactor's avatar

    coolfactor

    354 posts

    Neither custom routes nor the _remap() technique directly address this problem.

    Custom Routes would work if you had a pattern, such as:

    <a href="http://www.site.com/user-coolfactor/">http://www.site.com/user-coolfactor/</a>

    Then you could match the “user-” pattern, but that’s not what you want.

    The _remap() function only works once a controller has been chosen, so that needs to be done first, which is the essence of the problem to begin with.

    Personally, I would override the Router library with a MY_Router.php library and have a function in there that looks at the first segment of the url, checks a database for a matching username, and if it finds one, rewrites the url with the /member/ controller name. Otherwise, it simply passes control along to the default router, which would handle the request natively. Alternatively, it could see if the first segment matched one of the controllers, but this could could be complex if you plan on nesting controllers in subfolders (a feature of CI).

    I use this technique for special handling of images, css, and javascript files that I keep in my views folder. Whenever MY_Router sees “img”, “css”, or “js” as the first segment, it attempts to return the appropriate resource. Otherwise, routing continues normally.

    <a href="http://www.site.com/img/some_image.jpg">http://www.site.com/img/some_image.jpg</a>
    <a href="http://www.site.com/js/admin.js">http://www.site.com/js/admin.js</a>
    ...etc.

    Works like a charm.

  • #7 / Dec 12, 2007 2:52pm

    hotmeteor

    29 posts

    Can you give us an example of how you did it?

  • #8 / Dec 12, 2007 3:13pm

    coolfactor's avatar

    coolfactor

    354 posts

    My version is too complicated to post in its entirety, as it has a lot of code that doesn’t directly apply to this technique, but the gist of it is this:

    1. subclass Router to create MY_Router
    2. define “shortcuts” that it should recognize in the first segment of the url, such as “img”, “css”, “js”, etc.
    3. override the _parse_routes() function to look for shortcuts in the $this->segments array
    4. when it recognizes one of those shortcuts, take the rest of the url and search for a matching resource file anywhere you want those to be stored, such as in the Views folder.
    5. if it doesn’t recognize a shortcut, let the flow of control pass along to parent::_parse_routes() for normal operation.

    <a href=”/img/housing/doorstep.png”>
    might load an image at:
    /application/views/img/housing/doorstep.png

    I keep my application folder outside the webroot, so this technique lets me serve those files as if they were in the webroot.

    Because the Router is one of the first libraries to be loaded, this technique can take effect before loading the Controller, etc. While it works well, realize that there will be an ever-so-slight performance hit anytime PHP has to send out images, css and javascript files this way. Browser and server-side caching helps here.

  • #9 / Dec 12, 2007 3:16pm

    Michael Wales's avatar

    Michael Wales

    2070 posts

    Custom Routing works fine for me in this situation. The only downfall is you have to define your controllers prior to the open regex route that processes users (or pages, or whatever it is).

  • #10 / Dec 14, 2007 1:04am

    kilishan's avatar

    kilishan

    183 posts

    I had the same problem for an application that I’m writing. The solution I’ve found that works great is a combination of _remap and custom routing.

    The first thing I did was to implement the _remap function in the users controller. So it checks to see if segment 2 of the uri is a method of the class. If it is, run the method. If it isn’t, it’s assumed to be a username. So look up the id of the user and then pass that id to the index function, which then displays whatever default page you want them to see. Actually, my code also gets the owner of the profile it’s looking at, and the viewer of the page (based on session data) and makes those available in class variables for all of the functions.

    This allows this url to work: http://www.my-site.com/users/username. Almost there.

    Then, like Michael said, use a custom route as the very last route to send all reroute anything not redirected to the other routes to the user function. This gives you what you’re looking for, namely:

    http://www.my-site.com/username.

    Hope that helps.

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases