Remove /views/ from url with rewrite - .htaccess

I'm trying to learn how to use htaccess rewrite, but I just can't get the hang of it. What I'm trying to do is make the following urls:
mysite.com/
mysite.com/views/clients
mysite.com/views/projects
mysite.com/views/estimates
...look like this:
mysite.com/
mysite.com/clients
mysite.com/projects
mysite.com/estimates
It should be simple enough. But I just can't make it work.

Assuming the URLs in your app are already of the form /clients, not /views/clients, then try the following in the .htaccess file in your document root:
RewriteEngine On
# Remove "views" from all (typed) URLs with external redirect
RewriteCond %{THE_REQUEST} /views/([^\ ]*)
RewriteRule .* /%1 [R,L]
# Internally rewrite specific requests back to /views
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(clients|projects|estimates)/(.*) /views/$1/$2 [L]
Once you are satisfied this is working then change the R (temporary) redirect to R=301 (permanent).
This checks against THE_REQUEST before the redirect in order to prevent a redirect loop.

Related

.htaccess rewrite to same alias without infinite redirects

I have...
| .htaccess : (v1)
RewriteEngine on
RewriteRule ^in?$ login.php
So, /in --is-really--> /login.php
This much works great. We all can learn how to do this from: .htaccess redirect with alias url
But, I want it to also work in reverse...
If someone should enter /login.php into the address bar, I want it to change to /in.
So also, /login.php --rewrites-to--> /in
From this Answer to a different Question, I want to be ready for anything, using REQUEST_URI. So, my .htaccess file starts with this...
| .htaccess : (v2)
RewriteEngine on
# Remove index.php, if a user adds it to the address
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+/)?index\.php
RewriteRule (^|/)index\.php(/|$) /%1 [R=301,L]
# "in" --> login.php
RewriteRule ^in?$ login.php
That also works great.
But now, I want to add this rule (my Question here) for /in <--> /login.php both ways, just how / <--> /index.php already works with .htaccess (v2). So, I adopted the settings and added a second rule...
| .htaccess : (v3) —not working!
RewriteEngine on
# Remove index.php, if a user adds it to the address
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+/)?index\.php
RewriteRule (^|/)index\.php(/|$) /%1 [R=301,L]
# "in" --> login.php, and also redirect back to it
RewriteCond %{REQUEST_URI} ^/(.+/)?login\.php
RewriteRule (^|/)login\.php(/|$) /%1in [R=302,L]
RewriteRule ^in?$ login.php
...but then /in and /login.php both cause an infinite redirect loop.
What's the right way to do this, still using REQUEST_URI, and still having both rewrite rules (for index.php and for login.php)?
These Questions did not help:
Rewrite rule to hide folder, doesn't work right without trailing slash
This is not about a trailing slash
Allow multiple IPs to access Wordpress Site Admin via .htaccess
This is not about IP-based access
Htaccess URLs redirects are working for http not all https
This is not about https vs http
Rewrite-rules issues : .htaccess
This is not about cleaning up the GET array in the URL
apache htaccess rewrite with alias
This is not about rewriting the host/domain, thereby preserving the path
rewrite htaccess causes infinite loop?
This is not about www subdomain rewrites
.htaccess rewrite page with alias
This is not about rewriting "pretty" URLs nor about how to use slug settings in WordPress
Htaccess alias or rewrite confusion
This is not about simply having multiple rules with the same destination
htaccess rewrite to include #!
I'm not trying to rewrite #!
Reason of redirect loop is a missing RewriteCond %{ENV:REDIRECT_STATUS} ^$ before first redirect rule that removes index.php. Remember that RewriteCond is applicable to immediate next RewriteRule only.
Suggested .htaccess:
RewriteEngine on
# Remove index.php, if a user adds it to the address
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+/)?index\.php$ [NC]
RewriteRule ^ /%1 [R=301,L]
# "in" --> login.php, and also redirect back to it
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+/)?login\.php$ [NC]
RewriteRule ^ /%1in [R=302,L]
RewriteRule ^in?$ login.php [L,NC]
It won't cause redirect loop because after first rewrite to /login.php, variable REDIRECT_STATUS will become 200 and then the RewriteCond %{ENV:REDIRECT_STATUS} ^$ will stop redirect looping.
Thanks to the help from the user with the correct answer, I found that...
RewriteCond %{ENV:REDIRECT_STATUS} ^$
...doesn't go in .htaccess only once, but every time on the line before...
RewriteCond %{REQUEST_URI} ...

Apache redirect directive not acting as final rule

I am trying to achieve a simple redirect - from /news to /insights
I have the following in my .htaccess file:
redirect 301 /news /insights
<IfModule mod_rewrite.c>
RewriteEngine On
# Send would-be 404 requests to Craft
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
RewriteRule (.+) index.php?p=$1 [QSA,L]
</IfModule>
Whenever I've used the redirect directive before, any matched URLs would be redirected and no further rewrites in the file would be processed. That is to say, going to /news would send you to /insights, and the rewrite to index.php would not be processed.
However, with this current setup, going to /news sends me to /insights?p=news, so for some reason the rewrite to index.php is still being processed.
Furthermore, if I comment out the index.php rewrite, then I get sent to /insights as expected.
This isn't how I've usually experienced this working so am unsure why it's doing this.
I have also tried the following:
RewriteEngine On
RewriteRule "^/news" "/insights" [R=301,L]
This simply results in a 404 instead of redirecting, which I also do not understand.
I am aware I could do the following:
RewriteEngine On
RewriteCond %{REQUEST_URI} "^/news"
RewriteRule ^ /insights [R=301,L]
which does work, however, I don't really want to have multi-line rewrites for lots of URLs, and would like to understand why the other 2 examples do not work.
You just need to insert this rule before last catch-all rule.
RewriteRule ^/?news/?$ /insights [R=301,L,NC]
Place it just below RewriteEngine On line so that mod_rewrite engine executed this rule before other rule.
Make sure to test it in a new browser.

Rewrite, Redirect, and avoid duplicate content

I'm trying to redirect a single page using .htaccess. The actual file is /abc.php, I want it to appear as /abc. So these are my pseudo-rules:
if the user hits /abc.php, rewrite the url as /abc
if the user hits /abc, serve /abc.php
For SEO purposes, only one of /abc and /abc.php should be available.
My naive approach is this:
Redirect 301 /abc.php /abc
RewriteRule ^abcs$ /abc.php [NC,L]
This is causing infinite, looping redirects. How do I do this correctly?
You can use this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteBase /
# external redirect from actual URL to pretty one
RewriteCond %{THE_REQUEST} \s/+(abc)\.php[\s?] [NC]
RewriteRule ^ %1? [R=302,L]
# internal forward from pretty URL to actual one
RewriteRule ^(abc)/?$ $1.php [L,NC]

Change a url via htaccess

I had a website which url is http://www.testingmyweb.comli.com
In my website a had a folder TCWEB. My website is in this folder.
I want to map http://testingmyweb.comli.com/TCWEB/home.html to http://testingmyweb.comli.com/
What can I changes do in .htaccess file?
Based on your comment, your htaccess file looks like this:
RewriteBase /
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
Redirect /TCWEB/home.html testingmyweb.comli.com
The rule that you have appends .html to requests that are for html files (but don't have the extension). The redirect that you have underneath that needs to be removed. In order for you to rewrite / to /TCWEB/home.html, that mod_alias directive will cause a loop. Replace it with these rules:
RewriteRule ^$ /TCWEB/home.html [L]
RewriteCond %{THE_REQUEST} /TCWEB/home.html
RewriteRule ^ / [L,R=301]
The first rule makes it so requests for / maps to /TCWEB/home.html, but the URL in the browser's address bar remains http://www.testingmyweb.comli.com. The second rule does what the Redirect does, except it checks that the request was actually made for /TCWEB/home.html, and not an internally rewritten URI. So when someone goes directly to /TCWEB/home.html, they get redirected to /, then the first rule gets applied.

.htaccess redirect conflicts with another htaccess rule that I can not remove

The Information:
So I am fairly new to .htaccess and have being reading a bit.
Basically I want to do this, redirect the url www.example.com/center-pro to www.example.com/pro-hq
(found how here here .htaccess URL redirect)
However the site i am work on already has a .htaccess file in place.
This is what I am adding doing :
Options +FollowSymLinks #already in htaccess file
RewriteEngine On #already in htaccess file
Redirect 301 /center-pro http://www.example.com/pro-hq #line I added
RewriteCond %{REQUEST_FILENAME} !-f #already in htaccess file
RewriteCond %{REQUEST_FILENAME} !-d #already in htaccess file
RewriteRule ^(.*) index.php?idstring=$1&%{QUERY_STRING} #already in htaccess file
The last line seems to be messing with my redirect
So the output from my redirect looks like this :
www.example.com/pro-hq?idstring=center-pro
The Question:
Is there any way to have the redirect rule above and keep the current .htaccees so I don't mess up the current site settings.
** note: Doing a RewriteRule works but i would like to use a redirect so people don't share the wrong url.
You can use mod_rewrite for your external redirection too:
RewriteRule ^center-pro$ http://www.example.com/pro-hq [R=301,L]
This is probably the simplest solution, in place of your current Redirect. The problem is that mod_rewrite performs its work before mod_alias, and while the rewritten URI path is not passed along, the modified query string unfortunately is. You could also condition your RewriteRule to prevent it from processing the path you want handled by mod_alias, but I prefer the first option:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond ${REQUEST_URI} !^/center-pro
RewriteRule ^(.*) index.php?idstring=$1&%{QUERY_STRING}
Additionally, for your currentRewriteRule, you can just use the QSA flag instead of manually appending the query string to the URL:
RewriteRule ^(.*) index.php?idstring=$1 [QSA]

Resources