Welcome Guest, Not a member yet? Register   Sign In
URL Rewriting: Name instead of ID
#1

[eluser]perfectsam[/eluser]
Hi there

I'm using the bibliography management software www.aigaion.nl which uses the CI framework. I've already used the .htaccess to define a rule that removes the index.php from the URL.

The database consists, among other things, of publications, topics and authors. At the moment, the URLs look like this:

http://localhost/publications/show/744
http://localhost/topics/single/64
http://localhost/authors/show/281

Now would it be possible to show the publication/topic/author NAME instead of the ID in the URL, e.g.

http://localhost/authors/show/john_doe
or even http://localhost/authors/john_doe

How could this be achieved? Thanks.
#2

[eluser]WanWizard[/eluser]
Exactly the same way as you do now.

I assume you have a controller called "authors" with a method called "show", that uses the parameter (the number) to lookup a record. So you can do:
Code:
if ( is_number($parameter) )
{
    $result = $this->author_model->get_by_id( $parameter );
}
else
    $result = $this->author_model->get_by_name ( $parameter );
}
If you want the URL to change, then you can do a redirect to the name after get_by_id() is succesful.
#3

[eluser]WanWizard[/eluser]
If you want to remove the method name from the URL, you can use a route (how complex that is going to be depends on the other methods in your controller you want exposed). If show is the only method, you can also use the _remap() method.
#4

[eluser]mddd[/eluser]
That kind of rewriting cannot be done through .htaccess or CI routes, because you need to look up the name in the database.

If you exchange the id for the name, you must change your controller's methods to look up data by name instead of by id.

If you wanted to make something like authors/john_doe, you should make a _remap method in the authors controller. The _remap method is always called. In that method you can examine the uri and start the correct controller method.
#5

[eluser]KingSkippus[/eluser]
[quote author="perfectsam" date="1279641053"]Hi there

I'm using the bibliography management software www.aigaion.nl which uses the CI framework. I've already used the .htaccess to define a rule that removes the index.php from the URL.

The database consists, among other things, of publications, topics and authors. At the moment, the URLs look like this:

http://localhost/publications/show/744
http://localhost/topics/single/64
http://localhost/authors/show/281

Now would it be possible to show the publication/topic/author NAME instead of the ID in the URL, e.g.

http://localhost/authors/show/john_doe
or even http://localhost/authors/john_doe

How could this be achieved? Thanks.[/quote]

I would define in the controller two different functions in your controller, one to show by name and one to show by id. If this is software already in production use, I'd leave the show($id) function in your controller alone so that existing URLs and bookmarks don't break, and define a new function something like:

Code:
show_name($name) {
    if (isset($name) && strlen(trim($name)) > 0) {
        $this->load->view('author', array('name' => $name));
    }
    else {
        // Handle being passed a zero-length string
    }
}

You would access this function by http://localhost/authors/show_name/John Doe

As another user pointed out, read up on URI routing to shorten your URLs with just the ID or name. Again, though, if access has historically been via the URL with "show" in it, I'd leave that one alone.
#6

[eluser]perfectsam[/eluser]
[quote author="WanWizard" date="1279641818"]
Thank you all for your solutions.

@WanWizard
My structure is indeed as you described. I took your solution and my code looks like this now:
Code:
if (is_numeric($author_id))
    {
        $author = $this->author_db->getByID($author_id);
        redirect('authors/show/'.$author->getName());
    }
    else
    {
        $author = $this->author_db->getByName($author_id);
    }

Now I only have to write a function that converts the name (+special chars) into a conform URL segment, e.g. John Doe -> john_doe
#7

[eluser]KingSkippus[/eluser]
rawurlencode(string $str)

Know it. Love it.
#8

[eluser]mddd[/eluser]
Good solution. Some small things I thought of:

1. Why use a redirect? Why not have the page stay on its own url? It would be perfectly ok to do so. That way, name and id would be equal. Not having the name simply a redirect to the id. Think of bookmarking for instance. Wouldn't it be much nicer for the user to bookmark 'authors/john_doe' than 'authors/show/123' ? FAR more useful to keep the name in there! And better for SEO too, I would think.

2. If you use a REAL encoded string, including special characters, people won't be able to type it in. I mean, what user knows url encodings by heart? My guess is that it would be better to lose the accents and use 'regular people's writing'. authors/josé nuñez is a LITTLE BIT harder to read, let alone write, than authors/jose_nunez right? In the end, the whole point is to make urls more readable!
#9

[eluser]KingSkippus[/eluser]
[quote author="mddd" date="1279714564"]If you use a REAL encoded string, including special characters, people won't be able to type it in. I mean, what user knows url encodings by heart? My guess is that it would be better to lose the accents and use 'regular people's writing'. authors/josé nuñez is a LITTLE BIT harder to read, let alone write, than authors/jose_nunez right? In the end, the whole point is to make urls more readable![/quote]

I disagree with this in that URLs should always conform to RFC 1738 (see section 2.2). That means no accented characters and no spaces. This was updated recently to include Chinese characters, but still, don't go nuts. If you start using non-standard URLs, I guarantee that you will break something. Maybe not in your particular browser, but in some browser somewhere that actually adheres to the standards, you most certainly will.

The whole point is not to make URLs more readable. That's what search engines and internal navigational elements are for. The whole point is to uniquely define page locations. If a URL gives the user some clue as to what they will find at that location, all the better. If they are discernable to the point where a user can guess the location of something based on its name, that's gravy, not a requirement.

In the example you give, there's nothing particularly wrong with .../john_doe, but that means that the programmer is going to have to write his own my_urlencode() and my_urldecode() functions. It just seems like a waste to me when perfectly good, stable, tested a billion times ones already exist in the core php library. Writing your own is time and effort you can spend working on something else, it's one less thing you have to test and re-test, and it's one less point of failure that can break as you write and maintain your code. My consistent advice is don't reinvent wheels unless you have to, and prettifying URLs is generally not a "have to" reason.

Having said all of that, if you absolutely, positively must have prettified URLs, use CodeIgniter's url_title() function. At least someone else has taken the time to write, test, and maintain it, which is less work for you.
#10

[eluser]mddd[/eluser]
Then the topicstarter should just stick to using id's. I don't see the value in using names instead of id's, but encoding the names in a way that is hard to read by the user.




Theme © iAndrew 2016 - Forum software by © MyBB