Welcome to WebmasterWorld Guest from 34.207.78.157

Forum Moderators: Ocean10000 & phranque

Message Too Old, No Replies

User Friendly URLs with mod_rewrite, won't work

Use mod_rewrite with prg to create user friendly URLs

     
9:18 pm on Aug 11, 2005 (gmt 0)

Junior Member

10+ Year Member

joined:Aug 14, 2002
posts:153
votes: 0


I’ve read through many articles discussing “User Friendly URLs” and I have come to the conclusion that Apache module mod_rewrite and the use of an external prg (program) using preferably PHP but if necessary Perl, is the answer. If there is a better answer please let me know. As for now I can’t seem to figure out how to get my “User Friendly URLs” method to work using Apache mod_rewrite.

What I want to achieve is to create virtual paths such as www.domain.com/products/ or www.domain.com/products/erv/ with trailing slashes that is passed into mod_rewrite to process this virtual path. Which breaks up the path into separate values (i.e. “products”, “erv”). Then queries the database for the topic id to determine if “erv” and/or “products” exists. If it does exist the topic id would be returned to the page to be processed other wise a 404 error should occur to the client. I don’t want to have to input direct references to all the paths into Apache’s httpd.conf or .htaccess as I have 11 topics with 70+ sub-topics to deal with. Going to a database is the best option I believe. In theory this should work however I’ve tried my own mod_rewrite RewriteRules and RewriteMap with no success of a value being returned. I’ve even tried examples that demonstration a similar method but no success. If anyone has an idea how to achieve this or can direct me into the right direction please let me know.

PHP code example to break up the path into separate values.
list($value1, $value2, $value3) = explode(”/”, $_SERVER[’SCRIPT_URL’]);

httpd.conf mod_rewrite in VirtualHost directive.

RewriteMap content prg:/var/www/htdocs/venmar/getTopicId.php
RewriteRule ^(.*)/(.*)/$ /index.php?nTopicID=${content:$1¦0}

3:09 am on Aug 12, 2005 (gmt 0)

Senior Member

WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Mar 31, 2002
posts:25430
votes: 0


The_Warden,

From the looks of your RewriteRule pattern, I surmise that you are testing this code in .htaccess. Be aware that RewriteMap is not available in .htaccess, only in httpd.conf. So this may be a cause of trouble.

The simplest way to do this is probably to rewrite only "page" requests --not images, CSS stylesheets, external JS files, or robots.txt-- to your script. Then have the script verify that the requested content exists. If not, the script can output the 404 response header. This method simplifies the design and lets your database do all the work, for which it is best-suited.

Something like:


# If requested URI does not exist as a directory
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite request to script
RewriteRule ^(.+)/$ /index.php?nTopicID=$1 [L]

I have shown a very promiscuous pattern for the RewriteRule. Make it as specific as possible to avoid unnecessary checks for "directory exists" (The RewriteCond is processed only if the RewriteRule pattern matches -- See under "API phases" in the mod_rewrite documentation).

Make sure your script does not write any output to STD_OUT before deciding if the content exists. Otherwise, you will get the dreaded "headers already written" error message. You should only begin output once you know whether to return a 404-Not Found or a 200-OK response.

Jim

7:58 pm on Aug 16, 2005 (gmt 0)

Junior Member

10+ Year Member

joined:Aug 14, 2002
posts:153
votes: 0


I should have been more specific. I'm not doing this into a .htaccess file I'm doing all of this in my httpd.conf file.

Yes this is correct, however I still wish to achieve content request by a user going to /products/erv/, rather than /index.php?nTopicID=1&nValue=2&nValu3=1 using RewriteMap prg.

This is a great example however this is not what I'm wishing to achieve. I wish to do this using RewriteMap with prg as I don't want to manually have to enter 11+ topics and 70+ subtopics.

Yes this is what I'm concerned about and want to make sure this functions correctly.

10:23 pm on Aug 16, 2005 (gmt 0)

Senior Member

WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Mar 31, 2002
posts:25430
votes: 0


My main point is that you're using a method which will require you to maintain two databases; One used by your script to generate pages, and the other in the RewriteMap file. The method I attempted to describe simply passes all requests to your script, which could look up the product ID based on the URL, determine whether it exists or not, and serve the appropriate response, using the existing database.

However, if you want to use RewriteMap, then be aware that the pattern in .httpd.conf, unlike that in .htaccess, should start with a slash:


RewriteRule [b]^/([/b][^.]+)/([^/]+)/$ /index.php?nTopicID=${content:$1¦0}

The "not-a-slash" pattern shown will be much faster to process than multiple ".*" patterns, because it is less ambiguous.

Jim

5:47 pm on Aug 17, 2005 (gmt 0)

Junior Member

10+ Year Member

joined:Aug 14, 2002
posts:153
votes: 0


Oh no I don't want to do two databases. I thought I could just use RewriteMap prg. Ok I apologize for not understanding but by the example for mod_rewrite you gave previously that code would require an ID to be passed via the URL (without RewriteMap?) to be able to grab the requested content? If so this is not what I was wanting to achieve. As clients would just see directory paths such as /products/erv/ or /store/ or /support/literature/. There would be no corresponding value being passed via the URL at least visibly to the client in the address/location bar. That fake or virtual path would be taking by the script to determine what content was being requested by the client.

Oh I was not aware the / was required when doing this in the httpd.conf, thanks. Mmm well let me try this step and see if this works. But then again I don't want to do this as you say I would require two databases. Oh man I'm confused as to what to do to achieve my goals. Please tell me if I'm not making sense as to what I'm trying to do here (smile).

7:07 pm on Aug 17, 2005 (gmt 0)

Senior Member

WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Mar 31, 2002
posts:25430
votes: 0


What is needed:

  • Some way to "detect" that the URL needs to be passed to the script. This may be as simple as using "/products" as the identifier.

  • A simple mod_rewrite to rewrite those special URLs to your script. The script itself can then look at the requested URL and grab "/products/erv" or any other URL-based information to determine what content to serve.

  • Alternatively, mod_rewrite can take the identifying information from the URL and put it into a query string to be passed to the script. This would be an internal server operation, and would not be visible to the user.

    As long as the URL carries the information --regardless of form-- needed to determine that the request needs to be passed to the script, plus the information needed by the script to determine what content to serve, then this is both possible and easy, The only need for mod_rewrite is to pass the requests to the script, and to move the information into a query string if this is required to keep the script simple.

    It's quite possible that you are imagining this to be much more complicated than it is. But it's basically just identifying "special" requested URLs, passing those requests to the script, and giving the script the info it needs to decide what content to serve. It all boils down to passing the necessary information from a link on one of your pages clicked by a user, from the browser's HTTP request to the script.

    Rather than starting this thread with a specific implementation, it might have been better to to start with a "How do I?" - type query with some example URLs.

    Jim

  • 10:47 pm on Aug 24, 2005 (gmt 0)

    Junior Member

    10+ Year Member

    joined:Aug 14, 2002
    posts:153
    votes: 0


    Okay this all sounds great and I'm glad to hear that this is all possible. Now as you said in the last statement, you are right I should have done a "How do I" but I didn't unfortunately. So now I ask the question, How do I do that as at least the mod_rewrite part. After that I can easily handle the rest. You may be right that I'm complicating this more then it should be however I'm still not sure how I would do this. An example of How do I do this using the URL with just paths to draw content is what I wish to achieve with trailing slash (/). If that URL reference is not found it would give the usually 404 error message.

    Thanks for the help.

    7:40 pm on Aug 25, 2005 (gmt 0)

    Senior Member

    WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member

    joined:Mar 31, 2002
    posts:25430
    votes: 0


    The method posted in message #2 is as specific as I can get without "engineering" your entire interface, a job encompassing many issues beyond the scope of this forum.

    Jim

     

    Join The Conversation

    Moderators and Top Contributors

    Hot Threads This Week

    Featured Threads

    Free SEO Tools

    Hire Expert Members