htaccess - redirect a directory including the index page - .htaccess

I am updating a website and having updated a directory name, I need to update all links for the old directory named blog to the newly named press
I have tried this:
RewriteRule ^blog/(.*)$ /press/$1 [R=301,NC,L]
Which works perfect for any url's within that directory. i.e
website-url.com/blog/post-1
Goes too
website-url.com/press/post-1
However the blog index page still doesn't. I instead get a 404 when going to:
website-url.com/blog
If I have a trailing slash, it does work. Just not without.
I know I can use an absolute path redirect like so:
Redirect 301 /blog http://www.website-url.com/press
But the domain could change so I want to keep the path relative / dynamic for this.

Have your rule like this:
RewriteRule ^blog(/.*)?$ /press$1 [R=301,NC,L]
This will match /blog also as /.* part is optional match.

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!

URL rewrites issues

We are having a problem with URL rewrites on an apache server using .htaccess.
Goal: to have the following URL stripped of its category & subcategory while leaving the generic redirect in place.
Test 1:
Redirect 301 /category/subcategory/product http://www.site.com/product
Redirect works perfectly. A single redirect to the desired page.
Test 2:
RedirectMatch 301 ^/category/subcategory/.*$ http://www.site.com/category/subcategory
Redirect on its own works perfectly for all URLs desired.
The problem is when we have both URLs in a clean .htaccess file, and the redirects are in the proper order (specific first, then general), the general redirect is being used.
Test 3:
Redirect 301 /category/subcategory/product http://www.site.com/product
RedirectMatch 301 ^/category/subcategory/.*$ http://www.site.com/category/subcategory
When we visit www.site.com/category/subcategory/product, the result is www.site.com/category/subcategory/product, That is not the desired result. Instead, we want the URL to be www.site.com/category/subcategory/product,
We have even tried modified the Redirect to:
Redirect 301 /category/subcategory/product http://www.site.com/product [L]
It made no difference.
Please help!
EDIT: Added 3/25/2014
What we are trying to do is provide specific redirects for a group of known products from their old product page to the new product page. We are also trying to add a "catch all" redirect for the remaining unknown products to the category page.
Here is an actual example redirect which works:
Redirect 301 /womens/western-dresses/stetson-cream-empire-waist-ls-western-dress http://www.site.com/stetson-cream-empire-waist-ls-western-dress
If the above redirect is added to the .htaccess file, it works perfectly on its own.
Here is a second example redirect which works:
RedirectMatch 301 ^/womens/western-dresses/.*$ http://www.site.com/womens/western-dresses
The problem is if we have both of the rules together in .htaccess, in the same order as above, the second rule is always triggered. We try to access www.site.com/womens/western-dresses/stetson-cream-empire-waist-ls-western-dress and the result is www.site.com/womens/western-dresses instead of the desired result of www.site.com/stetson-cream-empire-waist-ls-western-dress
For clarity:
if we remove the .htaccess file, the URL 404s
if only the first rule is listed, it triggers perfectly
if only the second rule is listed, the second rule triggers perfectly
if both rules are listed, the second rule triggers.
We have deleted all redirects from the .htaccess file. The only redirects are the below two lines. The issue remains where the first redirect is ignored. We have tried changing the start of the first redirect to ^/womens and ^womens but that change had no effect.
Redirect 301 /womens/western-dresses/stetson-cream-empire-waist-ls-western-dress http://www.site.com/stetson-cream-empire-waist-ls-western-dress
RedirectMatch 301 ^/womens/western-dresses/.*$ http://www.site.com/womens/western-dresses
Your post is a little confusing, so I may be misunderstanding what you are trying to do.
If memory serves, you should not include a leading slash in your pattern when using these directives in a .htaccess file. That usage is reserved for httpd.conf. When these directives are used in a .htaccess file, the leading path components have already been stripped by mod_access. I am guessing this is the cause of your troubles.
For example, this should work (not tested):
Redirect 301 ^category/subcategory/product http://www.site.com/product
RedirectMatch 301 ^category/subcategory/.* http://www.site.com/category/subcategory
As an aside, [L] is mod_rewrite lingo. "Redirect" and "RedirectMatch" are part of mod_access.
EDIT 3/25:
Redirect and RedirectMatch can be fussy when used in .htaccess files, particularly when dealing with non-existent folders and mixed directives. Can I suggest you move directly to mod_rewrite? While it has a steep learning curve, you will never go back once you get the hang of it.
# Assuming you are in a .htaccess under DocumentRoot:
RewriteEngine On
RewriteRule ^category/subcategory/product1\.html$ /product1.html [R=301,L]
RewriteRule ^category/subcategory/product2\.html$ /product2.html [R=301,L]
RewriteRule ^category/subcategory/.* /category/subcategory [R=301,L]
As an aside, this looks like a good candidate for RewriteMap, although you will need to declare the map in your httpd.conf.

Url Mod-Rewrite Get new Page with ID

i need some help from the experts.
I have some rewrite rules:
post.php go to http://example.com/post/3/
RewriteRule ^post/([A-Za-z0-9-]+)/?$ post.php?id=$1 [NC,L]
It Works!
But, How can i add a new rewrite rule to the NEW Page Users.php after post/ID/
And get the ID in Users.php (Users.php?id=3)
Like this http://example.com/post/3/users
Thanks!
If you want /post/3/users/ to go to /Users.php?id=3, you have to put that rule before your existing rule. Your existing rule matches /post/3/' which is a prefix of what this additional rule matches, so that rule will never fire if it is after.
# catch the longer URL first
RewriteRule ^post/([A-Za-z0-9-]+)/users/?$ Users.php?id=$1 [NC,L]
# No /users/ on it; rewrite to post.php
RewriteRule ^post/([A-Za-z0-9-]+)/?$ post.php?id=$1 [NC,L]
Another thing: you tagged your post with .htaccess. Does that mean your rewrites are in a .htaccess? If so, you should use RewriteBase because your rewrites are relative. Why it's working is probably that you are allowing a 1:1 correspondence between paths and URLs on your webserver.
In a per-directory context like .htaccess, mod_rewrite is working with path names, not URLs. But if you do a relative rewrite, the path is turned into a URL and fed back into the Apache's request handling chain to be processed over again. How the path is turned into a URL is that the contents of RewriteBase are added to the front. If you don't have RewriteBase then a silly thing happens: the path to your directory (that was removed for the RewriteRule is just tacked back on!).
Example: suppose your DocumentRoot is /var/www. Suppose the browser asks for the URL /foo. This gets translated to the path /var/www/foo If inside the .htaccess for /var/www/ you rewrite foo to bar (and RewriteBase is not set), then mod_rewrite will generate the URL /var/www/bar: it just takes the /var/www/ directory that was stripped off and puts it back on. Now that can be made to work: just make /var/www/ a valid URL going to that directory. For instance with
Alias /var/www /var/www # map /var/www URL to /var/www directory
But that is hacky. The right way is to have RewriteBase / in the .htaccess. So when foo is rewritten to bar, it just gets a / in front and becomes the url /bar. This is fed back to the server and will resolve back to the document root again "naturally".
I used hacks like that before I understood the rewriting. I even used / as a DocumentRoot! That made everything work out since then most URLs are paths: you don't have to think of URLs a an abstraction separate from your filesystem paths. But it's a dangerous, silly thing.

Simple and neat .htaccess redirect help required

This is a strange one...
A while back I managed to write a .htaccess redirect that worked so that the URL was read like: www.website.com/mt?page=index - and what the real URL of this page was www.website.com/PageParser.php?file=index.php
The problem has been that the FTP system of my webhost hides .htaccess files even though they are allowed and do operate - and so I have checked back on local copies I have of my .htaccess files and none of them have the code as to how this works - and I've forgotten how I did it!!
Essentially, I am using wildcards so that anything after mt?page= will actually be showing PageParser.php?file= but without having the PageParser.php showing within the URL (and this is the important bit, because the index.php on my site root is actually sent through PageParser.php first so that anything which shouldn't be there is wiped out before the end user sees it) - so how can .htaccess redirect/rewrite the URL so that any link to /mt?page= show the file located at /PageParser.php?file= without changing the URL the user sees?
RewriteEngine On
RewriteRule ^(.*)mt?page=(.*)$ $1PageParser.php?file=$2
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^page=([^&]+)
RewriteRule ^mt$ /PageParser.php?file=%1.php [NC,L]
This rule will rewrite (internal redirect) request for /mt?page=hello to /PageParser.php?file=hello.php without changing URL in browser.
Your source URL example (www.website.com/mt?page=index) has index while target URL (www.website.com/PageParser.php?file=index.php) has index.php. The above rule will add .php to the page name value, so if you request /mt?page=hello.php it will be rewritten to /PageParser.php?file=hello.php.php.
If there is a typo in your URL example and page value should be passed as is, then remove .php bit from rewrite rule.
The rule will work fine even if some other parameters are present (e.g. /mt?page=hello&name=Pinky) but those extra parameters will not be passed to rewritten URL. If needed -- add QSA flag to rewrite rule.
This rule is to be placed in .htaccess in website root folder. If placed elsewhere some small tweaking may be required.
P.S.
Better write no explanation (I knew it/I did it before .. but now I forgot how I did it) than having these "excuses". While it may be 100% true, it just does not sound that great.

Resources