Is there a way to add IF to .htaccess? - .htaccess

I'm building a web-builder, but I have no idea how to use .htaccess. Is there a way to make something like that (I'll write it in php because my English bad so it is easier to me):
<?php
if(ERROR && ONE_NAME){ //There is no page like that, for example: www.example.com/thispageisntexists
//redirect to page /website.php?webname=thispageisntexists
}elseif(ERROR && TWO_OR_MORE){ //for example: www.example.com/thispageisntexists/hi.php
//redirect to page /website.php?webname=thispageisntexists&pagename=hi
//if url is www.example.com/thispageisntexists/hi.php#hi rediract to /website.php?webname=thispageisntexists&pagename=hi#hi
//if url is www.example.com/thispageisntexists/hi.php?name=vlad&last=gincher rediract to /website.php?webname=thispageisntexists&pagename=hi$name=vlad&last=gincher
//and so on...
}
?>
inside website.php I'll check if the page exist and if no it will redirect to 404.php, and if it exist it will show the website.

I find it somewhat unclear what url's should be redirected or rewritten. I am assuming you have (or want) seo urls like this http://example.com/aaa and http://example.com/aaa/bbb and want to internally rewrite that to something that makes sense to the server.
You want it to work if there is already a query string present. This means that you have to concat the two query strings with the [QSA] flag.
"There is no page like that" translates to a condition that checks if the requested filename exists. You can negate that condition with a ! before the second argument. That would be RewriteCond %{REQUEST_FILENAME} !-f.
#hi is an anchor. It is never sent to the server. Your browser should however automatically keep appending that to the url, even when redirecting the request.
I see that Jon Lin already posted a .htaccess file that should work for you. I will still post this answer to clarify what is used there.

Try:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/website\.php
RewriteRule ^([^/]+)$ /website.php?webname=$1 [L,R,QSA]
# you can remove the "R" if you don't want to redirect the browser
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/website\.php
RewriteRule ^([^/]+)/(.*?)(\.php)?$ /website.php?webname=$1&pagename=$2 [L,R,QSA]
# you can remove the "R" if you don't want to redirect the browser

There's nothing with such an explicit IF-THEN-ELSE. .htaccess does have ways of doing conditional URL/URI redirects and rewrites, using RewriteCond and RewriteRule commands. They use "regular expressions" to match patterns, so they aren't as flexible as a real scripting language like PHP, but you can do lots with them.
RewriteEngine On
RewriteCond %{REQUEST_FILE} !-f
RewriteRule /?(.*)$ /website.php?webname=$1 [L]
might be a start for what I understand you're trying to do.

Related

Htaccess for redirecting a directory to a file with the same name

After doing a quick lookup on how to manage sites with multiple language support, I find site.com/language/page/ the neatest url layout. (as I don't have the funds for site.language)
I have used htaccess to redirect the base site from site.com to site.com/language/
by using: RedirectMatch ^/$ /language/ where 'language' is language.html
But since I have a directory called /language/ so that all other pages in the given language can be put inside it, the site just shows up as the index of the directory.
How can I accomplish that kind of layout, if I want the main index page to show up in the url as site.com/language/ ?
Current htaccess that worked fine until I added the directory:
## Rewrite Defaults
RewriteEngine On
## Remove file extension + force trailing slash
RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule (.*)/$ $1.html [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule .* %{REQUEST_FILENAME}/ [R=301,L]
## Redirect to /en-gb
RedirectMatch ^/$ /en-gb/
With the root folder looking like:
/language
stuff.html
morestuff.html
language.html
...
I would really appreciate help as this is currently a nightmare situation. When I try compiling the htaccess with answers to similar questions, everyone has just parts of what I am looking to achieve and thus I break the layout with every modification...
Is it possible to change the back-end filenames and accomplish this layout using only htaccess for front-end url rewriting since the url bar is the only thing that matters?
If I understand correctly, you should be able to solve this by removing the line:
RewriteCond %{REQUEST_FILENAME} !-d
Let me know if that works.

how to rename a module in the url with mod_rewrite

I'm using MVC with /<module>/<controller>/<action>/ have a module at example.com/module/whatever, and I need to 'rename' it to example.com/module-a/whatever. The whole application is already written, so I can't go through and change it everywhere in my code, so I'm hoping to do it with mod_rewrite. I've tried the following
RewriteCond %{THE_REQUEST} ^GET\ /module/
RewriteRule ^module/(.*) /module-a/$1 [L,R=301]
which did what I wanted as far as redirecting all urls like example.com/module/whatever to example.com/module-a/whatever, but now I need all requests at 'module-a' to be internally rewritten as 'module'. It also needs to work for the module root (i.e. example.com/module with no trailing slash). Is this possible? I added
RewriteRule ^module-a/(.*)$ module/$1
directly beneath the above condition and rule, but when the page is accessed, it still says the module 'module-a' is not found.
Edit:
I have a few more rules below those, I wouldn't think they would affect this, but here they are anyway:
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Solution
I ended up using
RewriteCond %{THE_REQUEST} ^GET\ /module/
RewriteRule ^module$ /module-a [L,R=301]
RewriteRule ^module/(.*) /module-a/$1 [L,R=301]
to redirect all links from module to module-a. I had to do it with 2 rules because I don't know regex well enough to combine them, handling the special case of the url example.com/module.
To rewrite internally, the original rule I had would normally work, but Zend seems to do some stuff that overrides that, so I had to handle it with routes. See rename a zend module with routes
If I understand correctly then you've gone about this from the wrong direction. I am also not clear on the purpose of your RewriteCond
You want all module-a/* requests to be processed internally as module/*, so all you need is a simple rewrite::
RewriteRule ^module-a/?(.*) /module/$1 [L]
I suspect the problem you are having is the internal links on the site all reference /module/ rather than /module-a/, but putting a 301 there will cause no end of problems (not least with search engines), and with the subsequent rewrite you may fall into circular references. You are much better off changing the link code in your app (if you have a link abstraction class), or at worst using output buffering to swap all links out before rendering the page.
Note: The second rule below the above is not being processed if the first matched, as [L] causes mod_rewrite to cease processing if that rule is matched.

.htaccess Redirect

I need to create a redirect that sends the user to a specified php page with the variable of the page they originally requested, such as:
http://website.com/4
would send them to
http://website.com/download.php?id=4
However I don't want to redirect them if they request an actual page in the root directory, such as website.com/index.php.
Any idea how to accomplish this?
Should be exactly what you asked for; rewrites the URL to include download.php?id= unless the request is for any file that physically exists already:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ download.php?id=$1 [L]
Edit: I added the RewriteEngine On because it may not work without it depending on your server setup. To be fair, mlerley's answer reminded me that it should be there.
Assuming Apache 2.2:
RewriteEngine On
RewriteRule ^(\d+)$ /download.php?id=$1
The url doesn't change in this case. This also assumes that your id is always a number.

.htaccess mod_rewrite add "/" to the end of url

This is my .htaccess code:
RewriteBase /kajak/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^moduli/([^/]+)/(.*)$ moduli/$1/index.php/$2 [L]
Now / is appended to every URL. For example, http://127.0.0.1/moduli/novice becomes http://127.0.0.1/moduli/novice/.
How can I prevent getting / at the end?
While I do not know the answer to your question, I will note two oddities about your question and your code that may be related to the problem at hand.
With the RewriteBase you have in your code, those rules should not even be being triggered.
While I am new to regex myself, I look at ([^/]+) and am a little confused as to why you are capturing it. I know that ^ matches the START of the string, which would never be true since you already have another one at the real start of the string.
This being said, I would probably write the code as below:
RewriteBase /moduli/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)$ $1/index.php/$2 [L]
This would rewrite URLs as below:
http://www.website.com/moduli/novice/view
http://www.website.com/moduli/novice/index.php/view
Based on your block of code, this seems to be what you are trying to do. If it is not, then I am sorry.
I don't think that's related to your rewrite rule, (it does not match it).
The / is added because when you request http://example.com/xx/zz and the web server detects zz is a directory, it transforms it to http://example.com/xx/zz/ through a 301 redirect (the browser makes another request - check you apache logs).
Read about the trailing slash redirect thing here.
The, you must aks yourself, what do you want to happen when the url requested is http://127.0.0.1/moduli/novice/ (Do you want it to be be catched by your redirect or not? Currently it's not catched because of RewriteCond %{REQUEST_FILENAME} !-d)
BTW, I don't quite understand your RewriteBase /kajak/ line there - are you sure it's correct?

.htacces RewriteRule not working

Hi people#stackoverflow,
Maybe I have a fundamental misconception about the working of RewriteRule. Or maybe not. Nevertheless, I'm trying to figure this out now for two days, without any progress.
This is the currrent situation:
I have a Joomla website with SEF and mod_rewrite turned on.
This results in the URL:
mysite.com/index.php?option=com_remository&Itemid=7
being rewritten to:
mysite.com/sub-directory/sub-directory/0000-Business-files/
These are the lines that are currently used in my .htaccess (all standard Joomla)
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([^\-]*)\-(.*)$ $1 $2 [N]
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]
# RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{REQUEST_URI} (/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$ [NC]
RewriteRule (.*) index.php
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
This is what I want to achieve:
When a visitor uses this URL
mysite.com/sub directory/sub directory/0000 Business files/
it should lead him to the right page.
Although I know it's not the best idea to use spaces in a URL, I'm confronted with the fact that these 'spacious' URL's are used in a PDF, that's already been issued.
I thought I could use mod_rewrite to rewrite these URL's. But all I get is 'page not found'
I've added this rule on top of the .htaccess file:
RewriteRule ^([^\-]*)\-(.*)$ $1 $2 [N]
But this is not working. What am I doing wrong? Or, also possible, am I missing the point on when and how to use mod_rewrite?
rgds, Eric
First off, the default behavior of apache is usually to allow direct URLs that map to the underlying file system (relative to the document root), and you should use RewriteRule when you want to work around that. Looking at your question, it seems like you want to browse the filesystem and so you should not use a RewriteRule.
If mysite.com/sub+diretory/sub+directory/0000+Business+files/ doesn't work (without your rule), I'm wondering: do you have that directory structure on your server? I.e. does it look like this?
[document root]/index.php
[document root]/sub directory/sub directory/0000 Business files/
If not, I'm not sure I understand what you're trying to achieve, and what you mean by the visitor being "lead to the right page". Could you provide an example URL that the user provides, and the corresponding URL (or file system path) that you want the user to be served.
Regarding your rewrite rule, I'm not even sure that it is allowed, and I'm surprised you don't get a 500 Internal Server Error. RewriteRule takes two arguments (matching pattern and substitution) and optionally some flags, but because of the space between $1 and $2 you're supplying three arguments (+ flags).
EDIT: I got the pattern wrong, but it still doesn't make much sense. It matches against any URL that has at least one dash in it, and then picks out the parts before and after the first dash. So, for a URL like "this-is-a-url-path/to-a-file/on-the-server", $1 would be "this" and $2 would be "is-a-url-path/to-a-file/on-the-server". Again, if I had some example URLs and their corresponding rewrites, I could help you find the right pattern.
On a side note, spaces aren't allowed in URLs, but the browser and server probably does some work behind the scenes, allowing your PDFs to be picked up correctly.

Resources