Forum Moderators: phranque

Message Too Old, No Replies

Rewriting one folder deep

         

wheelie34

8:41 am on Jul 30, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi

I have read Jims' guide over and over but can't work out were I am going wrong, my urls look like

www.example.com/widgets/display.php?widgetname=xyz

I want to rewrite it to appear like this

www.example.com/widgets/xyz

So after butchering Jims example code here's what I ended up with


# Internally rewrite search engine friendly static URL to dynamic filepath and query
RewriteRule ^widgets/widgetname/?$ /widgets/display.php?widgetname=$1 [L]
#
# Externally redirect client requests for old dynamic URLs to equivalent new static URLs
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /widgets/display\.php\?widgetname=([^&]+)\ HTTP/
RewriteRule ^display\.php$ http://www.example.com/widgets/%1? [R=301,L]

I tested it and got no errors or hicups, but nothing changed? the usual path is still displayed, any ideas?

Second question, I take it my on page links to the OLD style URL will need changing to the new one?

wheelie34

11:51 am on Jul 30, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



an update, I have moved the htaccess file to the widgets folder, it seems (by looking at the error log) that it's the internal rewrite that's wrong I now get an error 500 with this line

RewriteRule ^widgetname?$ /display.php?widgetname=$1 [L]

I understand in Jims example code it would make the first bit a folder name, how do I make it the end result IE widgetname

jdMorgan

2:02 pm on Jul 30, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yes, in order to change what gets displayed, you must change the links on your pages.

If you get a 500 Error, look at the server error log -- It will often tell you exactly what is wrong.

Your rule is back-referencing an undefined value ($1), and the pattern appears to be wrong. Taking into account that you've moved the code into /widgets/.htaccess, try something like this:


RewriteRule ^([^./]+)$ /widgets/display.php?widgetname=$1 [L]

This will accept anything as "widgetname" as long as it contains no periods or slashes.

I don't know what you intended with the question mark on your pattern in the preceding post. Be aware that if left unescaped, a question mark is a regex quantifier meaning "match zero or one of the preceding character or parenthesized group." As such, your pattern would have matched "widgetname" or "widgetnam", but nothing else.

Jim

wheelie34

2:13 pm on Jul 30, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



thanks jim OK the internal rewrite now works, but if I call it the old way it still displays the old way, the redirect isn't kicking in, here's what I have

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /display\.php\?widgetname=([^&]+)\ HTTP/
RewriteRule ^display\.php$ http://www.example.com/widgets/%1? [R=301,L]

jdMorgan

5:47 pm on Jul 30, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



THE_REQUEST will always contain the HTTP request header exactly as received from the client. Therefore that RewriteCond pattern must contain the full URL-path, in contrast to the "localized" URL-path examined by the RewriteRule.

Jim

wheelie34

7:25 pm on Jul 30, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



got it, thanks Jim

wheelie34

8:48 am on Jul 31, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



OK this now works fine for ONE file, I have another file in the same folder that uses a different variable, I tied using the same code but changing the file name and variable but it tries to load the correct info but into the first file? here's what I have.

RewriteRule ^([^./]+)$ /widgets/display.php?widgetname=$1 [L]
#
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /widgets/display\.php\?widgetname=([^./]+)\ HTTP/
RewriteRule ^display\.php$ http://www.example.com/widgets/%1? [R=301,L]

########Second rewrite, same folder different file#########

RewriteRule ^([^./]+)$ /widgets/result.php?loc=$1 [L]
#
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /widgets/result\.php\?loc=([^./]+)\ HTTP/
RewriteRule ^result\.php$ http://www.example.com/widgets/%1? [R=301,L]

In order to rewrite the friendly results from the second file, is it possible? how

jdMorgan

1:46 pm on Jul 31, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Understand that your two internal rewrites (first and third rules) have exactly the same pattern, and will therefore match exactly the same requested URL-paths. So whichever comes first in the .htaccess file will always override the other. You must provide *some* information in the 'friendly' URL to allow you to use two different patterns, so that your rules can differentiate between the requested URLs to be rewritten to display.php versus those to be rewritten to result.php.

If it's not clear, the regex pattern on the left side of the rewriterule is applied to the URL requested by the browser, and translated to either an internal filepath (rewrite) or to a new URL (redirect) given on the right side of the rewriterule. So everything is based upon the URL requested by the browser, and whether it matches the regular-expressions pattern in the rewriterule. Mod_rewrite takes action as a request arrives at your server, before any content is served or any scripts are run. It translates incoming URL requests, and does not modify the content of your pages in any way.

Jim

wheelie34

2:43 pm on Jul 31, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Morning Jim, thanks for looking in again.

After reading your reply I undertsand a bit more how it works, I thought the passed variable name would be picked up but now see how it picks it up, I sent a test of sdhadsadadha (total junk) to see what happens and if I wasn't counting mysql rows it would have just displayed an empty page!

I think I am just going to make a seperate folder and 301 to that, I can't see anyway of passing the rewriterule any different info that it wont get confused, thanks Jim

jdMorgan

3:18 pm on Jul 31, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The whole problem is easier to understand if you use the link on a page as the "starting point" rather than considering, say, your script to be the starting point. Starting with a link on a page, the link defines the URL. The client browser requests that URL when the user clicks on the link. The browser request arrives at your server, and the server translates the requested URL into a filepath to 'find' the page it should serve in response to a request for that URL. This 'page' may be an existing static HTML file, or it may be produced (as in your case) by calling a script to generate an HTML page dynamically. The server then sends the contents of that page back to the requesting browser.

Nailing down the link on the page as the 'starting point' often clarifies many things. Another point to remember is that URLs and filenames are completetly different things, and need bear no resemblance to each other (thanks to mod-rewrite). The fundamental job of a server is to translate a URL to a filepath. And the purpose of a URL is to provide an 'addressing' system that can be used to locate a resource (a page, an image, etc.) regardless of the type of server, the hardware and operating system it runs on, the filesystem it uses, or the location of the requested resource within that filesystem. URLs are basically platform-independent "filenames" for use on the Web, and it pays to always keep URLs and filenames separate in your head.

Jim

wheelie34

3:42 pm on Jul 31, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi Jim, thanks again

Before I ask questions on how to send distinct keys to the rewrite can I ask you to look at this, when I hit the earlier problem I decided 3 result sets could go into their own sub folders, now I want to redirect the old dynamic call to the new folder via 301, here's what I have


RewriteCond %{QUERY_STRING} ^con=1$
RewriteRule ^(result\.php)?$ http://www.example.com/widgets/furry/ [R=301,L]

I end up with the correct page but have this in the browser address bar?

http://www.example.com/widgets/furry/?con=1

Now back to the original questions, so if I created a link that had a unique call in it how would I pick up that specific call, is that what your suggesting I do?

Thanks

jdMorgan

3:56 pm on Jul 31, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Answer to first question: You left off the question mark on the substitution URL. See examples in the code your posted earlier. The question mark in the substitution clears the pre-existing query string; Without it, that query string passes through mod_rewrite unchanged (See mod_rewrite documentation).

I don't understand your second question, specifically the term "call." Please provide examples.

In order to trigger different rules, the URLs in your on-page links must contain *something* to differentiate one from another.

Jim

wheelie34

4:22 pm on Jul 31, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Found the ? ;) thanks

Instead of using ([^./]+) is it not possible to specify a different variable name for it to look out for, for instance

RewriteRule ^variable1=([^./]+)$ /widgets/display.php?name=$1 [L]
RewriteRule ^variable2=([^./]+)$ /widgets/other.php?name=$1 [L]
variable2=abc

In theory both variables could be handled by one script which would mean all calls would be similar but, as in my needs, would of been shown on the wrong page, as it did, how would this normally be handled when rewriting for friendly URL's

jdMorgan

4:54 pm on Jul 31, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



First before you head down a wrong path here, the "variable=" is not part of a URL, and so cannot be 'seen' by RewriteRule. You have to use a RewriteCond to examine query strings.

Secondly, these query strings are not part of your URL, or at least they shouldn't be. The whole point of this exercise appears to be to get rid of query strings appended to your URLs. And again, it's URLs, not filenames, that RewriteRule examines. You must make your on-page URLs for the two scripts different -- The URLs themselves must tell RewriteCond which script to call.

How you do that is completely up to you.

You must add *something* to the URLs on your page, whether it may be to use URLs like:

/green-widget/display
/green-widget/other

or some variation of that idea, like:

/dsply-green-widget
/other-green-widget

or even

/d/green-widget
/o/green-widget

How you do it doesn't matter, except that RewriteRule must be able to look at *some* part of the two URLs linked-to by your page, and decide which script to call.

Jim

wheelie34

7:32 pm on Jul 31, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



OK, so it seems the one I setup yesterday isn't actually what I needed as it closed of the whole folder to any other queries.

this one


RewriteRule ^([^./]+)$ /widgets/display.php?widgetname=$1 [L]

So, if working in the widgets folder (which can recieve numerous different URL's) can they be caught and processed to 301 to a different folder?

I have created the folder /newfolder/ and placed an index.php file in it that will do the db call, the htaccess file within that folder contains

RewriteRule ^([^./]+)$ /widgets/newfolder/index.php?loc=$1 [L]

which again catches ANY URL's that come in, this works fine, it's the 301 redirects from old to new that's causing some headache, here's what I have in the htaccess file in the /widgets/ folder as that's where the request would arrive.


RewriteCond %{QUERY_STRING} ^loc=([^./]+)$
RewriteRule ^(index\.php)?$ http://www.example.com/widgets/newfolder/%1? [R=301,L]

Can you tell me whats wrong please, or if it's at all possible, I need to have the 301 in place.

EDIT
Got it, the index\.php needed changeing to the result\.php of the widgets folder, it works perfect now, thanks