Forum Moderators: phranque

Message Too Old, No Replies

rewrite to not need a subdirectory in URL

         

HDClown

2:34 pm on Jan 10, 2015 (gmt 0)

10+ Year Member



I have a site structure similar too:

/
/index.php
/page1.php
/folder1
/folder1/index.php
/folder1/somefile.php
/mc/jdoe
/mc/jdoe/index.php
/mc/jdoe/somefile.php
/mc/jsmith
/mc/jsmith/index.php
/mc/jsmith/somefile.php

... and so on

In the /mc/ subfolder, there are over 100 subfolders based on usernames and on a weekly basis some may be added or deleted.

Instead of making users go to http://www.example.com/mc/<username> I want them to be able to go to http://www.example.com/<username> and have it load content in http://www.example.com/mc/<username> folder

I'd like to be able to do this without having to manual maintain unique rewrite rules for every /<username> -> /mc/<username> redirect, just 1 rule to handle all of them.

Is this possible, given that I also have /folder1 that would NOT redirect anywhere? Seems like one way or another I'm going to have to maintain manual rules.

[edited by: Ocean10000 at 4:32 pm (utc) on Jan 10, 2015]
[edit reason] Examplified [/edit]

lammert

7:48 pm on Jan 10, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Hi HDClown, first of all Welcome to WebmasterWorld!

You can do this with a rewrite rule which first checks if a physical file, directory or symbolic link with that name exists.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ... here comes your rewrite rule ...

lucy24

10:48 pm on Jan 10, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Ouch, that's a lot of lookups. Alternative approach:

RewriteCond %{REQUEST_URI} !^(mc|directory|otherdir|thirddir)$
RewriteRule ^(\w+)$ /mc/$1.php [L]


where the RewriteCond lists the directories that physically exist (including /mc/ itself). If you don't use extensionless URLs elsewhere, you've already excluded most possibilities. This form will lead to 404 responses if someone requests "example.com/abcde" where no "example.com/mc/abcde.php" exists-- but the server has to do the lookup sooner or later and in this situation it may as well be later.

What happens if, in spite of this shortcut, a user chooses to request /mc/myname.php? Is Duplicate Content an issue? You'd have to either redirect (using a RewriteCond looking at %{THE_REQUEST}) or be willing to accept two URLs for identical content.

HDClown

2:32 am on Jan 11, 2015 (gmt 0)

10+ Year Member




Ouch, that's a lot of lookups. Alternative approach:

RewriteCond %{REQUEST_URI} !^(mc|directory|otherdir|thirddir)$
RewriteRule ^(\w+)$ /mc/$1.php [L]


In doing some testing, I modified your example to:

RewriteCond %{REQUEST_URI} !^(mc)$
RewriteRule ^(\w+)$ /mc/$1 [L]

And what I've found is that if I go to http://www.example.com/userA and http://www.example.com/mc/userA subdirectory exists, the content from /mc/userA is loaded. If there is no matching subdirectory in /mc then I get a 404. However, if there happens to be an actual matching subdirectory in the root, it will load that root subdirectory content.

So, this seems to be doing what I need assuming no one actually ends up adding "index.php". If I browse to http://www.example.com/userA/index.php I get a 404, it doesn't redirect to /mc/userA/index.php

Additionally, the rule is changing what shows in the browser address bar. When I go to /userA and the rule invokes, my address bar changes to /mc/userA. Any way to not have the URL in the address bar change?


What happens if, in spite of this shortcut, a user chooses to request /mc/myname.php? Is Duplicate Content an issue? You'd have to either redirect (using a RewriteCond looking at %{THE_REQUEST}) or be willing to accept two URLs for identical content.


I'm not sure I follow what you are saying here

lucy24

3:15 am on Jan 11, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



If I browse to http://www.example.com/userA/index.php I get a 404, it doesn't redirect to /mc/userA/index.php

That seems reasonable, since you don't want your users accessing pages by multiple different routes. In fact you should have an "index.php" redirect somewhere further along-- or rather, earlier in .htaccess, since you're talking about internal rewrites. But read on.

If the address bar is changing, you're doing one or both of two things wrong: either the RewriteRule itself has an [R] flag, or the target of the rewrite begins in http://www.example.com. The rule itself should only say
RewriteRule ^(\w+)$ /mc/$1/index.php [L]

with whatever Conditions you decide are appropriate. Note that since this is an internal rewrite rather than an external redirect, it is correct and appropriate to say explicitly "index.php" at the end. In an external redirect you will never show this part.

I now realize I misread your original post: the "real" URL is not
/mc/jdoe.html
but rather
/mc/jdoe/index.php
Oops.

All this is assuming you've got a hand-rolled site, possibly with your own rewriting. If it's a CMS doing things on its own initiative, we will need to hammer out some details.

NO files exist at example.com/jdoe/index.php

Right. But also no files exist at example.com/jdoe -- and right now, you're permitting two ways to view the same content:
example.com/jdoe
example.com/mc/jdoe/index.php
If you don't want this, you'll need an external redirect earlier in your htaccess, looking like this

RewriteCond %{THE_REQUEST} /mc/
RewriteRule ^mc/(\w+)(/(index.php)?)?$ http://www.example.com/$1 [R=301,L,NS]

That's if you want to allow for all possible requests:
example.com/mc/jdoe
example.com/mc/jdoe/
example.com/mc/jdoe/index.php

This is with the further assumption that you've got a DirectoryIndex line elsewhere, naming "index.php".

The overall order of these RewriteRules should be:

-- Redirect any request in /mc/name/index.php to preferred URL in form /name alone (rule has [R] flag)
-- Redirect any other requests for "index.php" to whatever the directory is (again with [R] flag)
-- Rewrite requests for /blahblah to /mc/blahblah/index.php (rule ends in [L] flag only)