htaccess directory - .htaccess

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^admin/([^/]+)/([^/]+).php website.com/admin/index.php?route=$1/$2 [NS]
RewriteRule ^modules/([^/]+)/([^/]+).php website.com/admin/index.php?route=$1/$2 [NS]
the above works for when you login. it goes to /admin/modules/catalog but when you click on a link that shows up in the status bar as /admin/vendors/ it doesnt work???? which vendors is a sub dir or modules/
any idea

Considering what is said in the documentation about RewriteCond, and what you get, I'd say that the RewriteConditions are only applied to the one RewriteRule that follows :
The RewriteCond directive defines a
rule condition. One or more
RewriteCond can precede a RewriteRule
directive. The following rule is then
only used if both the current state of
the URI matches its pattern, and if
these conditions are met.
What if you try duplicating those RewriteCond in front of the second RewriteRule ? At least as a test ?
And here is an interesting thing about the S|Skip flag. Amongst other things and an example, it is said :
The [S] flag is used to skip rules
that you don't want to run. This can
be thought of as a goto statement in
your rewrite ruleset.
And also :
This technique is useful because a
RewriteCond only applies to the
RewriteRule immediately following it.
Thus, if you want to make a
RewriteCond apply to several
RewriteRules, one possible technique
is to negate those conditions and use
a [Skip] flag.
I've never tried this, but it might be useful, in your situation... maybe ^^
Still, it's some part of the Apache's documentation that seem to indicate what I said earlier is right.

Assuming poor English?
It sounds like you're requesting /admin/vendors; but you're saying that vendors is located in /modules.

Related

htaccess rewriterule generating multiple copies of wrong match

Trying to use prettyURLs rewritten to php param qrys using .htaccess rules.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^foo/?([^/]*)/?([^/]*)/?$ /foo.php?s=$1&c=$2 [NC,END,R=301,QSA]
RewriteRule ^bar/?([^/]*)/?$ /bar.php?s=$1 [NC,END,R=301,QSA]
The first rule works correctly, but the second one generates:
https://example.com/bar.php?s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=.php&s=45843
from
https://example.com/bar/45843
RewriteCond directives are only applied to the single RewriteRule immediately following them. That means that your second RewriteRule is not covered by any RewriteCond. Which means it creates an endless rewriting loop.
You want to reject that, pointing out that you rewrite to /bar.php which is not matched again by the matching pattern maybe, but ...
That is not true actually. Take a closer look at your rule:
RewriteRule ^bar/?([^/]*)/?$ /bar.php?s=$1 [NC,END,R=301,QSA]
The matching pattern uses /? which makes the slash optional . So bar.php?s=whatever is again matched. In the next round the rewriting engine does.
Solution:
apply the conditions to both rules and
use a proper matching pattern.
Actually I am not sure what you are trying to match with those patterns ... Why the /??
Are you trying to match a query string that way? That won't work, you need another RewriteCond for that applyiong a matching pattern against %{QUERY_STRING}. That is documented, actually.
Or are you trying to make anything after /bar optional ? Then use a pattern like ^/?bar(/[^/]*)?/?$ maybe ...

url rewriting with htaccess not working

I am trying to rewrite my urls in my site so whatever is after the slash is passed as an argument (example.com/Page goes to example.com/index.php?page=Page)
here is the code that isn't working (it gives a Forbidden):
RewriteEngine On
RewriteRule ^/(.+)/$ /index.php?page=$1 [L]
Any Help will be appreciated
This is what I suggested in the comment to your question:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteRule ^(.+)$ /index.php?page=$1 [L,B]
The leading slash does not make sense in .htaccess style files, since you do not process an absolute oath in there, but a relative one. About the trailing slash: your example does not show such a slash, so why do you want to have it in the regular expression? It results in your pattern not matching anything but a request terminated by a slash. Which is not what you want.
The RewriteCond lines are there to still allow access to physical existing files and directories and to prevent an endless loop, though that should not occur with an internal-only rewriting. And you need the B flag to escape the part of the request url you want to specify as GET argument.
The last condition is actually obsolete, since obviously /index.php should be a file. I leave it in for demonstration purposes.
In general it is a very good idea to take a look at the documentation of apaches rewriting module: httpd.apache.org/docs/current/mod/mod_rewrite.html
It is well written, very precise and contains lots of really good examples. It should answer all your questions.

mod_rewrite match from start of URI

Good afternoon,
I am having considerable difficulty getting my mod_rewrite rules to match from the start of the URI. I've looked through the manual but I must be missing some (probably obvious) syntax voodoo. Please consider the following:
RewriteCond %{REQUEST_URI} ^/(.*)/(foo|bar)/(.*)
RewriteRule ^(.*)/(.*)/(.*)/ destination.php?first=$1&second=$2&third=$3 [QSA,L]
If the 2nd URI parameter is foo or bar, (e.g. url.com/first/foo/third) this successfully redirects to destination, with the relevant parameters.
If foo or bar are present in the 3rd parameter (e.g. url.com/first/second/foo), I want a different redirect to occur. However, the following rule is ignored, with the above rule still taking priority
RewriteCond %{REQUEST_URI} ^/(.*)/(something-else)/(.*)
RewriteRule ^(.*)/(.*)/(.*)/ destination.php?first=$1&second=$2&third=$3 [QSA,L]
I think I must be missing an obvious way of forcing the rewrite to only match from the beginning of the URI- I've tried prepending slashes to try to force it to the root level, but without any joy so far.
Any help would be greatly appreciated!
Thanks
Edit
As it turns out, this was due to a basic RegEx mistake, rather than my mistakenly assuming the match needed to begin from the start of the URI. I won't edit the title as others may make a similar mistake.
.* is too greedy. Try these 2 rules:
RewriteRule ^([^/]+)/(foo|bar)/([^/]+)/?$ destination.php?first=$1&second=$2&third=$3 [QSA,L]
RewriteRule ^([^/]+)/([^/]+)/(foo|bar)/?$ destination2.php?first=$1&second=$2&third=$3 [QSA,L]

mod rewrite exclude all but php

Is it possible to edit htacces in such a way that only the following url is rewritten and the rest isn't?
http://www.example.com/index.php?x=foobar
to
http://www.example.com/foobar/
I want the pages not having x=... as a variable to behave normally
I got the following but that doesn't work
Options +FollowSymLinks
RewriteEngine on
RewriteRule (.*)/ index.php?x=$1
RewriteCond $1 !\.(js|ico|gif|jpg|png|css|html|swf|mp3|wav|txt)$
Who can help me?
First off, the RewriteCond must be put before the RewriteRule to which it belongs.
But I think that you need another approach for your case, something like this:
RewriteRule (.*)\.php - [PT,L]
RewriteRule ^(.*)/$ index.php?x=$1
The first rule Passes Through (PT) every PHP page, so the second rule is only applied to all non-PHP requests.
That second rule only applies to a "simple path", no matter if this path has a dot in it or not (e.g. hello.gif/ will match, too).
If this does not work for you, then you might consider one of these points to start further research:
the pattern ([^\.]*) matches everything that does not have a dot in it
see RewriteCond to skip rule if file or directory exists for RewriteConds where the following RewriteRule is only used if the request does not point to an existing file or directory
Hope this helps.

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.

Resources