Rewrite Subdomain To non-existing Subdirectory - .htaccess

post edited with better current example.
I am looking for the best way to redirect my subdomains to subdirectories which do not really exist as subfolders.....
in a nutshell, the script I am using for a website allows for setting up geographic regions as subdomains..... but each region MUST have a unique subdomain and I really do not want to have 3-level subdomains (state, city, neighborhood) for my regions and the "big boys" in my niche all opt to use a single subdirectory (like /neighborhood-city,state/) so I am looking for the best way to point my subdomains to subdirectories, although they do not actually exist....
I currently have this in the htaccess as a rewrite:
RewriteRule ^/?([0-9]+)/([^./\\"'?#]+)\.html$ index.php?a=5&b=$1 [QSA,L] ##category
which rewrites to the url to: mydomain/cat#/catname.html
I want the URL/links to have this non-existing "region" subdomain-as-subdirectory added after the /catname/ but not sure how to modify this rewrite so that instead of having:
subdomain.mydomain/cat#/catname.html
I would have:
mydomain/cat#/catname/subdomain(value).html

The not found error is normal because you redirect your subdomains to nonexistents directories, which are not rewrited. Besides your redirection, you have to rewrite these directories so that the server knows where it can find the real files. So, try this code :
RewriteEngine On
RewriteRule ^([^/]+)/(.*)$ http://$1.domain.com/$2 [L]
Of course, you have to change this path to the good.

Related

Eliminate duplicate directory name in url using .htaccess file

For some reason, I'm getting duplicate directory names in some urls within a subfolder on our website. This seems to affect only crawlers as the files within this directory work fine when navigated.
I'd like to simply remove the duplicate directory name and make mydomain.com/sub/sub redirect to mydomain.com/sub.
I've tried many versions but my .htaccess skills are lacking apparently. I currently have (not working of course):
RewriteRule ^mydomain.com/sub/sub/(.*) mydomain.com/sub/$1 [L,R=301]
RewriteRule ^mydomain.com/sub/sub/(.*) mydomain.com/sub/$1 [L,R=301]
The RewriteRule pattern matches against the URL-path only - you appear to have included (part of) the domain name. Also, mydomain.com in the substitution string is going to be seen as a relative subdirectory.
Assuming you have a limited number of subdirectories where this occurs then to reduce /sub/sub/<something> to just /sub/<something> you would do something like this:
RewriteEngine On
RewriteRule ^sub/sub/(.*) /sub/$1 [R=301,L]
If you have other directives in you .htaccess file, then this needs to go near the top.
First test with 302 (temporary) redirects to avoid potential caching issues. Clear your browser cache before testing.
But to echo #arkascha's comment... the reason why crawlers are finding these URLs in the first place would seem to be a fault in your URL structure/internal links - so this is what ultimately needs to be fixed.

htaccess rewrite url by matching only the first part of the url

I've been struggling to find a solution to this very simple problem. You would think that this is the classic "please help me I need to redirect this url to newurl" type of thing but, believe me, it isn't that easy.
I have a domain example.com, this example.com has some language variants:
example.com/mx
example.com/us
example.com/ca
example.com/cl
example.com/xx
and so on, example
.com is the index to choose between countries and it exists too but has no content.
We recently moved our example.com/mx to a whole new domain (with a different system) example.com.mx so we proceeded to permanently redirect every url there to the its new url in the example.com.mx
While we were at it, we discovered that our multilingual wordpress installation on example.com was duplicating all website's content in the root file, something which shouldn't have happened.
So, we have like
example.com/us/folder
example.com/cl/folder
example.com/ca/folder
etc
AND
example.com/folder which shouldn't exist
There are tons of directories that are duplicated there, we already know where to redirect each of these directories but we just can't find the right line of code to do it.
For example, we have set up this htaccess rule to deal with all the /mx/ folder, which works well:
RewriteRule ^mx/shop/ https://www.example.com.mx/? [L,R=301]
RewriteRule ^mx/home/ https://www.example.com.mx/? [L,R=301]
RewriteRule ^mx/page/ https://www.example.com.mx/? [L,R=301]
RewriteRule ^mx/tag/ https://www.example.com.mx/? [L,R=301]
But when trying to extend this same logic to the "/shop/" directory, it matches the same directory in EVERY country folder, something we obviously don't want.
This is what we tried, described previously:
RewriteRule ^/tag/ https://www.example.com.mx/newtagurl? [L,R=301]
This obviously also redirects example.com/ca/tag/, because the ^.
So my question is, how to properly redirect to these cases ONLY matching the beginning https://example.com/tag/ string instead of matching every /tag/ case in every country folder?
Thanks!

Can one include separate files in htaccess for a list of redirects?

My main htaccess file does a bunch of things for my site to function correctly.
I have added redirects for pages that have moved. I don't have root access to the server and using .htaccess is my only option.
Is it possible to include separate files for the redirects in the .htaccess file so I can keep them separate and write programatically to the additional files that hold my redirects?
Basically I want to reference separate files from my .htaccess to manage rules dynamically and also neaten up one long .htaccess file with a few smaller files.
I also want to add redirect rules on the fly as things change on the site within my application.
You can use a RewriteMap http://httpd.apache.org/docs/2.3/rewrite/rewritemap.html
Let's say your map file looks like this and is called moved.map:-
/about profile
/page/that/has/moved new/location
You .htaccess would need something like this:-
RewriteMap moved txt:moved.map
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond ${moved:%1|NOT_PRESENT} !NOT_PRESENT [NC]
RewriteRule .? ${moved:%1} [NC,R=301]
This will redirect with a 301 status code http://your.domain.com/about to http://your.domain.com/profile and redirect http://your.domain.com/page/that/has/moved to http://your.domain.com/new/location
You can then programmatically create moved.map.
I hope that helps.
If you are using .htaccess files then don't bother with RewriteMap -- it only applies if you have root access to the server or vhost config, which is never the case when you purchase a shared service offering.
If you are constrained to use .htaccess files then you have two options:
The first is to do what some packages do and that is to get your application to rewrite the .htaccess file based on a rewrite map that you maintain within in it. The best way to do this is to have "bookends" in your .htaccess file e.g.
##++AUTOMATIC rewrite rules
<rules inserted by your app>
##--AUTOMATIC rewrite rules
And when an update occurs have your app read in the .htaccess, swap out the section between ##(++|--)AUTOMATIC rewrite rules, write it back to a temp file, then move the temp file to .htaccess (this makes the rewrtie-back atomic on *nix OSs).
The second which might work if you know some regexp regular pattern which covers the rewrites (this is often the case) then use a rule to map them to a redirector script which looks up the new target and itself issues a:
$server = $_SERVER['HTTP_HOST'];
header( "Location: http://$server/$newTarget?$parameters", TRUE, 301 );
Note the 301 redirect -- this means that client browsers should cache this and remember this in future.

htaccess redirect rules - How to redirect up one level?

http://mysite.com/level-1/level-2/level-3/
I want to redirect to
http://mysite.com/level-1/level-2/
"level-1" and "level-2" can be anything the user enters... (not these exact words)
Could you direct me to a tutorial or give me a few pointers?
Thanks a lot!!
Based on your comment (from level-3 to level-2 folder EXACTLY with 301 Permanent Redirect):
RewriteEngine On
RewriteBase /
RewriteRule ^([^/]+/[^/]+/)[^/]+/$ http://www.example.com/$1 [QSA,R=301,L]
This rule will redirect example.com/hello/pink/kitten/ to example.com/hello/pink/
If URL structure is different, then NO redirect will occur:
missing trailing slash (e.g. example.com/hello/pink/kitten)
4-level deep URL (e.g. example.com/hello/pink/kitten/family/)
This rule needs to be placed in .htaccess in website root folder. If placed elsewhere (e.g. Apache config file, inside <VirtualHost>, for example) the rule needs small tweaking.
You just want to throw away what's after the second slash. This is an easy rule:
RewriteRule ^(.*?/.*?/).+$ $1
Then investigate whether you want things like [L,QSA]. You may or may not.

Use htaccess to mask folder name

Here's a problem I'm always wanting to solve with htaccess. I haven't found a way yet, though it looks like it should be possible - perhaps someone can help.
Let's say I have a folder at the root of my site called /foo/. I want users to be able to access that folder at the path /bar/, but for various reasons I can't rename the folder.
So as not to create confusion I only want one path to ever be seen - that is to say, I don't want people to use the name /foo/ to access the folder; they should always use /bar/. If someone goes to example.com/foo/, their browser should redirect to example.com/bar/ - but the content returned should be the content of /foo/.
To make matters more complicated, pages in /foo/ have dependencies (images, stylesheets, links to other pages, etc) within /foo/ which are hardcoded and can't be changed. These must, of course, still work.
So, to summarise, this is what I want :
Requests for example.com/foo/ should redirect to example.com/bar/.
Requests for example.com/bar/ should return the contents of example.com/foo/.
Is this possible? It looks on the surface as if it would create an infinite redirect... but I'm pretty sure there are ways to prevent that in htaccess, aren't there?
I'd be very grateful for any help.
(PS - for a little extra background: The normal reason I want to do this is to rename the wordpress /wp-admin/ directory to something more professional and easy for customers to remember, such as /admin/. But the same system should work for masking any path in this way.)
I found a sort of workaround - by using a symlink and htaccess in combination.
First I created a symlink from /bar to /foo/.
Then I put this in htaccess :
Options +FollowSymLinks
RewriteRule ^foo/(.*)$ bar/$1 [R,L]
This has exactly the desired result - example.com/bar/ shows the content of the /foo/ directory, and example.com/foo/ redirects to example.com/bar/
But if anyone can come up with a pure htaccess solution I'd much prefer that!
Update :
Ok, I've finally found out how to do this. It turns out to be quite simple...
RewriteCond %{THE_REQUEST} ^GET\ /foo/
RewriteRule ^foo/(.*)$ bar/$1 [R,L]
RewriteRule ^bar/(.*)$ foo/$1
The only problem is that it doesn't take account of RewriteBase, so you have to include the full path in the first line (after ^GET\).
If I understand correctly what you want is something like this inside your .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^foo/$ bar/
RewriteRule ^bar/$ foo/
</IfModule>

Resources