views:

272

answers:

6

Let me start off by saying that I've got very little experience with web-development.

My question is simple, (taking SO as an example), how does the following work?

http://stackoverflow.com/tags/foo
http://stackoverflow.com/tags/bar

I've seen a lot of sites that do this, but I still don't know how this is accomplished (I'll be working on a LAMP stack, if it matters).

+3  A: 

What you want is clean URLS and you can do it with apache and .htaccess . There may be a better way, but here's how I have been doing it:

http://evolt.org/Making_clean_URLs_with_Apache_and_PHP

easement
To clarify- StackOverflow doesn't "hide extensions," it uses MVC to define Routes, which correspond to Views.
Dave Swersky
They correspond to controller methods, normally, but many of those have identically named views.
JasonTrue
+2  A: 

That's the beauty and the work of ASP.NET MVC.

No "hiding" - it's just the way ASP.NET MVC handles URL's and maps those "routes" to controller actions on your controller classes.

Quite a big step away from the "classic" ASP.NET Webforms way of doing things.

marc_s
I'm looking forward to this coming to web forms in ASP.NET 4.0
Russ Cam
Yes, me too! :-)
marc_s
A: 

There are a couple of ways to do it under Apache+PHP, but the essential principle is to make a set of URIs (perhaps all URIs, depending on your site, but you may want different scripts to handle different portions of the site) translate to a single PHP file, which is told what object the user has requested.

The conceptually simplest way is to rewrite every URL to a script, which gets the URI through $_SERVER['REQUEST_URI'] and interprets it as it likes.

The URI rewriting can be done with various methods including mod_rewrite, mod_alias and ErrorDocument (see Apache docs).

Another way is to set up more complex URL rewriting (probably using mod_rewrite) to add the path as a GET variable.

There is also the $_SERVER['PATH_INFO'] variable which is loaded with the non-existent portion of the path. This option requires little or no modification to Apache config files, but reduces the flexibility of your URLs a little.

Artelius
+5  A: 

When a web server gets a request for a URL, it has to decide how to handle it. The classic method was to map the head of the URL to a directory in the file system, then let the rest of the URL navigate to a file in the filesystem. As a result, URLs had file extensions.

But there's no need to do it that way, and most new web frameworks don't. They let the programmer define how to map a URL to code to run, so there's no need for file extensions, because there is no single file providing the response.

In your example, there isn't a "tags" directory containing files "foo" and "bar". The "tags" URL is mapped to code that uses the rest of the URL ("foo" or "bar") as a parameter in a query against the database of tag data.

Ned Batchelder
Thanks for the explanation.
sels520
A: 

Modern web development frameworks have support for elegant urls. Check out Django or Ruby on Rails.

Juanjo Conti
A: 

If you're using Apache and you simply want to hide the file extensions of static HTML files you can use this .htaccess code:

<IfModule mod_rewrite.c>
RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f       # if the requested URL is not a file that exists
RewriteCond %{REQUEST_FILENAME} !-d       # and it isn't a directory that exists either
RewriteCond %{REQUEST_FILENAME}\.html -f  # but when you put ".html" on the end it is a file that exists
RewriteRule ^(.+)$ $1\.html [QSA]         # then serve that file

</IfModule>

Apache mod_rewrite has been called "voodoo, but seriously cool voodoo.

I once worked out some much longer but far more readable code to do the same thing on a Zeus server. I can probably dig it up if you're interested.

The actual .htaccess code I use on a few sites is like that, but not identical:

<IfModule mod_rewrite.c>
    RewriteEngine on

    #RewriteRule ^$ index.php [QSA]
    RewriteCond %{REQUEST_FILENAME}\.php -f
    RewriteRule ^(.+)$ $1\.php [QSA]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.+)$ index.php/$1 [QSA]

</IfModule>

Edited to add rewrite rules from Zeus rewrite.script

# http://drupal.org/node/46508


# get the document root
map path into SCRATCH:DOCROOT from /
# initialize our variables
set SCRATCH:ORIG_URL = %{URL}
set SCRATCH:REQUEST_URI = %{URL}

match URL into $ with ^(.*)\?(.*)$
if matched then
  set SCRATCH:REQUEST_URI = $1
  set SCRATCH:QUERY_STRING = $2
endif

# prepare to search for file, rewrite if its not found
set SCRATCH:REQUEST_FILENAME = %{SCRATCH:DOCROOT}
set SCRATCH:REQUEST_FILENAME . %{SCRATCH:REQUEST_URI}

# check to see if the file requested is an actual file or
# a directory with possibly an index.  don't rewrite if so
look for file at %{SCRATCH:REQUEST_FILENAME}
if not exists then
  look for dir at %{SCRATCH:REQUEST_FILENAME}
  if not exists then
    look for file at  %{SCRATCH:REQUEST_FILENAME}.php
    if exists then
        set URL = %{SCRATCH:REQUEST_URI}.php?%{SCRATCH:QUERY_STRING}
    else
        set URL = /index.php/%{SCRATCH:REQUEST_URI}?%{SCRATCH:QUERY_STRING}
    endif
  endif
endif
goto END
TRiG

related questions