Forum Moderators: phranque

Message Too Old, No Replies

URL rewriting question

Want to use page-title URLs to access my CMS

         

base

12:54 pm on Nov 20, 2008 (gmt 0)

10+ Year Member



I see that this is a very asked question around here (and everywhere else to:).
I am having problems with it too, and I cant get is to work.

I would like to tranform:

http://www.example.com/category/index.php?get=72

to:
http://www.example.com/category/unique-title-of-the-same-page

using PHP/MySql/Apache and the .htaccess file.
The page titles are unique for every page and i retrieve it from the database using the get id.

Thank You (very much) in advance.

jdMorgan

3:58 pm on Nov 20, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Unless you have server configuration privileges, your best option it to rewrite (using mod_rewrite, or optionally if on Apache 2.x or above, using AcceptPathInfo) all requests for any URL beginning with "category/" to a single script -- either "index.php" or another "wrapper" script which will #include "index.php". This script must query the database to translate "unique-title-of-the-same-page" to "get=72", or perhaps index.php can be modified to use "unique-title-of-the-same-page" to generate appropriate content, instead of using "get=72" as the database query key.

If you do have server config privileges, you could define a RewriteMap to invoke a small friendly URL translation script which accesses your database to look up the "get=" value. But this is typically a PERL script, and it is separate from your main script. As such, this solution may be unnecessarily complex if you can just modify your existing PHP script instead.

After you get the friendly URL translation or direct lookup working, you might want to build a second, simpler script in PHP or PERL. You would rewrite all direct client requests for the old index.php?get= URLs to this second script, and it would look up the new "friendly" URL in your database and generate a 301-Moved Permanently redirect to that new "friendly" URL. This would aid in speeding up search engine indexing of the new URLs, and in recovering traffic from bookmarks saved by previous visitors, and in recovering both traffic and PageRank/Link-popularity from old links on other sites.

I italicized the "direct client requests" phrase above because this is a little tricky. You must use a RewriteCond to check THE_REQUEST to be sure that you are redirecting only the index.php?get= requests received directly from the Web client, and not those resulting from the previous internal rewrite that calls the script(s). If you don't use this check, then this new redirect and the previous rewrite will countermand each other, resulting in an 'infinite' rewrite-redirect loop. Several examples of how to do this are posted here in this forum, but for the sake of maintaining thread focus, we can discuss this step later when you've gotten the other changes working.

Jim

base

5:03 pm on Nov 20, 2008 (gmt 0)

10+ Year Member



I wish it was my own cms.

I wouldn't have used a number id, but the stored title as the get reference.

So basically i have to make another index.php file for every category with the new url?
And a script that translates get id's to cropped titles?
I'm really stuck with this..

(Thank You for your time btw)

jdMorgan

5:45 pm on Nov 20, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Depending on your URL-architecture, you may be able to get away with a single script. The requirement is that *some* information carried in the "friendly" URL must identify it as a URL that should be rewritten to the URL-translation script. This is so you can come up with a regular-expressions pattern that matches all URLs that need to be translated and send only those URLs to the translation script.

In the case of the URL you posted, it might be as simple as detecting any URL that starts with "category/" but does not end with "index.php" -- Note that query strings are not part of the URL, but rather, they are data appended to a URL, to be passed to the resource at that URL. This is a common point of confusion, so I thought I'd mention it.

So your old method was probably "link to /category/index.php with a query string of 'get=<id-number>'." The new method is:
Detect requests for "/category/index.php" and rewrite them to "/wrapper.php", located either in /category/ or in the site's root directory. If located in /category, you will need to exclude this path from being re-rewritten as well as the "/index.php" path previously noted.

Wrapper.php takes last path-part of the friendly URL, and uses it to query the database to look up the "get=<id-number>" value.

It then constructs a file #include directive to include "/category/index.php?get=<looked-up-value>" from the local filesystem, essentially making the /category/index.php script part of the wrapper script.

This may all sound scary, but if you break it down into small pieces, it's not so bad. You can probably copy the database-open and database query routines from your original /index.php file, and then just modify the query to use the friendly URL-path as the lookup key to retrieve the "get=" value. Then close the database, and #include the /index.php file in-line. Then exit.

A minor complexity is that if the database open or friendly-URL to get= translation database query fails, you need to send an appropriate 404-Not Found, 410-Gone, or 503-Service Not Available response, instead of calling the /index.php script. Use 404 if no entry can be found, and use 410 if you find a database entry that contains a token that says that the item or page is no longer available or existent, as appropriate.

Whatever you do, do not allow the script to "die" if an error occurs! -- You must either call the /index.php script after a successful lookup, issue one of the 4xx error responses noted above, or issue the 503-Service Not Available response if the database cannot be opened or if the lookup returns a non-data-value-related error.

Jim

base

11:54 am on Nov 22, 2008 (gmt 0)

10+ Year Member



Hy, just a little extra question..
Is this possible using PHP inside my index.php for the given category using a 301 redirect:

Divert from

www.domain.com/subcat/index.php?get=234

to:
www.domain.com/subcat/same-page-title

When clicked (or url hand-written):

www.domain.com/subcat/same-page-title

back to:
www.domain.com/subcat/index.php?get=234

and the URL in the address bar stays:
www.domain.com/subcat/same-page-title

Thanks.

jdMorgan

3:19 pm on Nov 22, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



A redirect will change the address bar. That is its definition.

You may be able to do most of this work in the php script *if* you rewrite *all* extensionless URL requests to your index.php script. This will result in a critical rule, though: None of your extensionless "title" URLs will be allowed to contain a period or a slash. If they do, they will not work.

Jim

base

3:56 pm on Nov 22, 2008 (gmt 0)

10+ Year Member



Could you be more specific?

I tried to, and will, keep all page titles (that's the nature of the site) simple (no exclamation,dashes,or alike), and i would like change the title using a simple str replace to replace spaces with dashes, and uppercase to lower case.

jdMorgan

1:22 am on Dec 2, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Not sure what you are asking about, here.

You need to take two steps:

Internally rewrite all requests for URLs which do not resolve to existing files or directories and which do not contain periods or other indicators that they refer to "real" files to your script.

If you get a direct client request for an old-format, query-string URL, then externally redirect that to the new "friendly" URL.

The code for both of these functions is posted in many of the threads here that deal with "friendly URLs" being rewritten to scripts.

Jim