Welcome to WebmasterWorld Guest from 3.93.75.30

Forum Moderators: Ocean10000 & phranque

Message Too Old, No Replies

rewrite with htaccess in sub directory

     
12:01 am on Feb 26, 2012 (gmt 0)

Preferred Member

10+ Year Member

joined:May 20, 2003
posts: 493
votes: 0


This may have been discussed before, but with the keywords I was searching for, I got a lot of posts that weren't relevant...

So, here's my problem. This is the URL I want to type into the address bar: [domain.com...] and it will access this file (sorry if my wording is wrong): [domain.com...]

My directory structure is as follows:
/
/work/
/work/files/
/work/files/project_number/
/work/files/project_number/key/

I want the .htaccess file in the /work/ directory. That is creating a problem because the typed in URL (http://domain.com/work/files/ABC0123/749152/) I guess does not see the .htaccess file in the /work/ directory, so the rewrite does not work (I did test it in the root directory .htaccess file and the rewrite did work, but I'd rather keep this rewrite in the /work/ directory). Here is my .htaccess file:

Options +FollowSymLinks
RewriteEngine on

#rewrite dynamic file URLs
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^work/([^/]+)/([0-9]+)/$ /work/files.php?project_number=$1&key=$2 [L]
RewriteRule ^work/([^/]+)/([0-9]+)$ /work/files.php?project_number=$1&key=$2 [L]


Any tips to get this to work?
12:06 am on Feb 26, 2012 (gmt 0)

Senior Member

WebmasterWorld Senior Member g1smd is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:July 3, 2002
posts:18903
votes: 0


The path is localised "per-directory" before being resented to mod_rewrite i.e. the details of higher folders is stripped from the beginning.

Your RewriteCond applies only to the single rule that follows it.

By allowing URLs that end either with or without a slash to be rewritten you promote Duplicate Content. Redirect "with trailing slash" to "without trailing slash" as your first rule with a RewriteRule that issues a 301 redirect.

Next, list your standard non-www to www redirect code. This uses another RewriteCond/RewriteRule pair.

Lastly, list your internal rewrite and make it accept only extensionless request without a trailing slash.
3:45 am on Feb 26, 2012 (gmt 0)

Preferred Member

10+ Year Member

joined:May 20, 2003
posts: 493
votes: 0


I'm not in control of most of the site and these files are not meant to be spidered/search engine accessible, so I'm not too concerned about duplicate content and the like. I did actually do the trailing slash thing though, just for my future reference. I also played around with a couple of other things and realized that the RewriteCond didn't seem to be doing anything - when I commented it out, the redirect/rewrites still worked. I thought the RewriteCond was necessary for the ([^/]+) = $1 type of stuff?

Anyway, this is my .htaccess now.


Options +FollowSymLinks
RewriteEngine on

RewriteRule ^work/([^/]+)/([0-9]+)/$ /work/$1/$2 [R,L]
RewriteRule ^work/([^/]+)/([0-9]+)$ /work/files.php?project_number=$1&key=$2 [L]


As for my main problem (getting the .htaccess file to work in the /work directory, I'm not understanding what you said....
7:17 am on Feb 26, 2012 (gmt 0)

Senior Member

WebmasterWorld Senior Member g1smd is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:July 3, 2002
posts:18903
votes: 0


The redirect is a 302 redirect. Change it to a 301. Add the protocol and hostname to the redirect target.

The path is localised "per-directory" before being resented to mod_rewrite i.e. the details of higher folders is stripped from the beginning. This means that the RegEx pattern should not mention any folders that are higher than the folder where the .htaccess file is located.
7:57 am on Feb 26, 2012 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:15810
votes: 847


Overlapping g1 just to show how very, very slowly I type

RewriteCond %{QUERY_STRING} ^$

= If there is no query string.

The reason it seems to make no difference is that you've only tested the rewrite with requests that are supposed to work. You also need to test it with requests that are supposed to not work-- including garbage requests.

RewriteRule ^work/([^/]+)/([0-9]+)/$ /work/$1/$2 [R,L]
RewriteRule ^work/([^/]+)/([0-9]+)$ /work/files.php?project_number=$1&key=$2 [L]

Didn't you start out saying that the htaccess is located in the /work/ directory? Seems like the Rewrites would then only work --haha-- if the request is for

/work/work/blahblah

Even if you never expect anyone-- or any search engine-- to see the result, say [R=301] just to get in the habit. The default unfortunately is 302 (same as with mod_alias redirects).

RewriteRule ^work/([^/]+)/([0-9]+)/$ /work/$1/$2 [R,L]

= a request for /work/directoryname/number(s)/ with trailing slash is externally redirected to /work/directoryname/number(s) without trailing slash.

Can I assume that the string of numbers is not an actual directory? Otherwise you will run afoul of mod_dir, whose job is to put back the slash.

Incidentally, you don't need to break the capture-and-reuse into two pieces just because there's a directory slash.

work/([^/]+/[0-9]+)/$ /work/$1

will do the same job in a nanosecond less time. But separating them will do no harm if it's easier for you to keep track of the rules that way.

RewriteRule ^work/([^/]+)/([0-9]+)$ /work/files.php?project_number=$1&key=$2 [L]

= request for /work/directoryname/number(s) without trailing slash is internally rewritten to serve content from /work/files.php with query string project_number=directoryname and key=number(s)

You should probably spend a little time looking at all the things that can possibly happen to a query string. The default behavior is that the pattern side of the Rule doesn't "see" the query string, just like it doesn't "see" the domain name; the target side of the Rule reappends the query string unless you've replaced it with a new one.

In your first Rule, the redirect, you probably want to play it safe by attaching ? to the target, meaning "throw out the query string if there was one". Your second rule as written will replace any existing query; this is probably what you want.

It looks as if you are doing the redirect-plus-rewrite two-step. It has three parts; you've got two of them. The third part may be what you were trying to do with your original Condition: make sure you're only redirecting brand-new requests that came in from "outside", not your newly rewritten requests. One ridiculously easy approach is

RewriteCond %{THE_REQUEST} \?

meaning: only apply this rule if the original request contained a question mark (i.e a query string).

Leave a blank line after every RewriteRule, and include a #comment line explaining what the rule does. This will make sense when you look at your htaccess in 2027-- or possibly next week-- and can't remember what the Rule was supposed to do.
 

Join The Conversation

Moderators and Top Contributors

Hot Threads This Week

Featured Threads

Free SEO Tools

Hire Expert Members