i'm trying to rewrite my urls to goto a single php file:
RewriteRule ^dir/(?:(?!style|js).)*$ http://www.domain.com/single.php?uri=$1 [QSA]
However the exclusion of /dir/js and /dir/style isn't working as i was hoping it would...
[redirects] domain.com/dir
[redirects] domain.com/dir/jason
[redirects] domain.com/dir/jason/pete
[DOESN'T REDIRECT: GOOD] domain.com/dir/js
[DOESN'T REDIRECT: GOOD] domain.com/dir/js/*
[DOESN'T REDIRECT: BAD] domain.com/dir/json
How can I change the regular expression to match my needs?
Try to replace style|js with style\b|js\b.
Maybe RewriteCond could be of use like in
RewriteCond %{REQUEST_URI} !^/dir/(style|js)($|/)
RewriteRule ^/dir/(.*)$ http://www.domain.com/single.php?uri=$1 [QSA]
EDITED:
domain.com/dir/json doesn't redirect because it doesn't match the regex.
The reason /dir/json doesn't redirect is because js follows dir/, and your regex only matches when dir/ is not followed by either style or js. I think negative lookaheads are the wrong approach. I think what you actually want is something like:
RewriteCond %{REQUEST_URI} !^/dir/(js|style)(/.*)?$
RewriteRule ^dir/(.*)$ http://www.domain.com/single.php?uri=$1 [LQSA]
That basically means if the URL isn't ended with /js or /style (optionally with further path components underneath those dirs), then apply the redirect rule.
Either with your negative look-ahead assertion:
RewriteRule ^dir/(?!(?:style|js)(?:/|$))(.*) http://www.example.com/single.php?uri=$1 [QSA]
But that’s not so nice.
Or you just add another test on how $1 starts:
RewriteCond $1 !^(style|js)(/|$)
RewriteRule ^dir/(.*) http://www.example.com/single.php?uri=$1 [QSA]
Related
I'm new to the rewriting of urls and regex in general. I'm trying to rewrite a URL to make it a 'pretty url'
The original URL was
/localhost/house/category.php?cat=lounge&page=1
I want the new url to look like this:
/localhost/house/category?lounge&page=1
(like I say, I'm new so not trying to take it too far at the moment)
the closest I've managed to get it to is this:
RewriteRule ^category/(.*)$ ./category.php?cat=$1 [NC,L]
but that copies the whole URL and creates:
/localhost/house/category/house/category/lounge&page=1
I'm sure, there must be an easy way to say copy all after that expression, but I haven't managed to get there yet.
I will try to help you:
You probably have already, but try a mod rewrite generator and htaccess tester.
From this answer: The query (everything after the ?) is not part of the URL path and cannot be passed through or processed by RewriteRule directive without using [QSA].
I propose using RewriteCond and using %1 instead of $1 for query string matches as opposed to doing it all in RewriteRule.
For your solution, try:
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^house/category$ house/category.php?cat=%1 [NC,L]
This will insert the .php and cat= while retaining the &page=
Anticipating your next step, the below mod rewrite may help get started in converting
http://localhost/house/category/lounge/1
to
http://localhost/house/category.php?cat=lounge&page=1
Only RewriteRule necessary here, no query string:
RewriteRule ^house/category/([^/]*)/([0-9]*)/?$ house/category.php?cat=$1&page=$2 [NC,L]
Use regex101 for more help and detailed description on what these regexes do.
If it still not working, continue to make the regex more lenient until it matches correctly:
Try to remove the ^ in RewriteRule so it becomes
RewriteRule category$ category.php?cat=%1 [NC,L]
Then it will match that page at any directory level. Then add back in house/ and add /? wherever an optional leading/trailing slash may cause a problem, etc.
Thanks for all your suggestions, I took it back to this
RewriteRule category/([^/])/([0-9])/?$ category.php?cat=$1&page=$2 [NC,L]
which has done the trick, and I'll leave it at this for now.
I am trying to redirect the following URL:
url/efx.aspx?xxxxxxx
to url/car-audio/efx-hardware/amp-install-kits
However it is redirecting whatever contains efx.aspx with the letters without the ? sign. I was wondering how I can fix this?
for example it is redirecting the following:
domain.com/efx.aspxlsdkjfhlasdf
but it is not redirecting
domain.com/efx.aspx?lsdkjfhlasdf
here is the .htaccess rule I wrote. how can I correct it?
RewriteCond %{REQUEST_URI} /efx.aspx[^/]+$
RewriteRule (.*) /car-audio/efx-hardware/amp-install-kits [R,L]
You can use this rule:
RewriteRule ^efx\.aspx$ /car-audio/efx-hardware/amp-install-kits? [R=301,NC,L]
Query string is not part of REQUEST_URI hence [^/]+ after efx.aspx fails your rule.
Also ? at the end of target URI removes any existing query string.
When using categories in ExpressionEngine, a Category URL Indicator trigger word can be set to load a category by its {category_url_title}.
I would like to remove the category "trigger word" from the URL.
Here is what I have so far, with the trigger word set to "category":
RewriteRule /products/(.+)$ /products/category/$1 [QSA,L]
I'm not an expert at writing regular expressions, but I do a little. I'm 99% sure my RegEx is fine, however when trying to use it as a RewriteRule in my .htaccess file, I'm getting a 500 error.
I'm sure it's something stupid, but for some reason I'm not seeing my mistake. What am I doing wrong?
Update: Adding a ^ to the beginning of the RewriteRule fixed the 500 error.
RewriteRule ^/products/(.+)$ /products/category/$1 [QSA,L]
This is not safe. Take:
/products/a
The regex group matches a.
It will be rewritten to:
/products/category/a
which the regex matches again (this time, the group matches category/a). Guess what will happen.
You want /products/ from the beginning of input if it is not followed by category/, which means you want a negative lookahead. Also, the QSA flag is of no use, you don't have a query string to rewrite (QSA stands for Query String Append):
RewriteRule ^/products/(?!category/)(.+) /products/category/$1 [L]
Another way to use it (and which I personally prefer) is to use a RewriteCond prior to the rule:
RewriteCond %{REQUEST_URI} ^/products/(?!category/)
RewriteRule ^/products/(.*) /products/category/$1 [L]
This Apache RewriteRule should do the job for you*:
RewriteCond %{REQUEST_URI} ^/products/(?!category/)
RewriteRule ^/products/(.*) /products/category/$1 [L]
With this in place, you'll need to hard code your category links manually:
{categories backspace="2"}
{category_name},
{/categories}
Which would output the new Category URLs you desire:
http://example.com/products/toys
Otherwise, if using the recommended path variable when building your category links:
{categories backspace="2"}
{category_name},
{/categories}
Would create links with the Category URL Indicator in the URI:
http://example.com/products/C1
http://example.com/products/category/toys
Which — while perfectly valid — would create canonicalization issues on your site since the different URLs would appear as duplicate content to search engines.
*Credit to fge for brilliant mod_write rule.
I need to match two cases
js/example_directory/example_name.js
and
js/example_directory/example_name.js?12345
(where 12345 is a digit string of unknown length and the directory can be limitless in depth or not exist at all)
I need to capture in both cases everything between js/ and .js
and if ? exists capture the digit string after ?
This is what I have so far
^js/(.*).js\??(\d+)?
This works except it also captures
js/example_directory/example_name.js12345
I want the regex to ignore that. Any suggestions?
Thank you all!
Test your patterns here
Answer:
Using Gumbo's information my final rewrite rule is as follows.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{QUERY_STRING} ^\d*$
RewriteRule ^js/(.*)\.js$ js.php?f=$1.js&v=%0 [L]
</IfModule>
Include the whole querystring pattern, including the ? in one conditional match.
^js/(.*).js(\?\d+)?
mod_rewrite’s RewriteRule directive does only test the URI path and not the query. So using a rule like the following does already match both URIs:
RewriteRule ^js/(.*)\.js$ …
If you now want to test the query too, you need to use an additional RewriteCond:
RewriteCond %{QUERY_STRING} ^\d*$
RewriteRule ^js/(.*)\.js$ …
The match of the last successful RewriteCond can be referred to with %n, so in case of the whole match %0 or in this case even just %{QUERY_STRING} directly.
As far as regular expressions go - you can use the (?:) (non capture grouping) to make the \?(\d+) as a chunck, optional like so:
^js/(.*).js(?:\?(\d+))?
You really don't >need< to use the ?: (non capture) portion, but if you don't, back references will be changed - 1 will point at the filename, 2 will point at ?1234 and 3 will be 1234
Im just learning mod_rewrite and regex stuff, and what I'm trying to do is pass variables of any name, with any number of variables and values, into a script and have them forwarded to a different script.
here is what I have so far:
RewriteEngine on
RewriteRule ^script\$(.*[\])? anotherscript?ip=%{REMOTE_ADDR}&$1 [L]
That all seems to work except that one of the parameters I'm passing is a URL and the // after http:// always gets stripped down to one slash.
for example, I do
script$url=http://www.stackoverflow.com
then it redirects to:
anotherscript?ip=127.0.0.1&url=http:/www.stackoverflow.com
and the second script chokes on the single-slash.
I realize that preserving a double-slash is the exact opposite of what people usually do with mod_rewrite. Is there a way I can preserve the double-slash?
EDIT: Solution found with Gumbo's help.
RewriteCond %{THE_REQUEST} ^GET\ (.*)/script\$([^\s]+)
RewriteRule ^script\$(.*) anotherscript?ip=%{REMOTE_ADDR}&%2 [L]
I had to add that (.*) in front of /script on the RewriteCond, once I did that it got rid of the 404 errors and then it was just a matter of passing the matches through.
Try this rule:
RewriteCond %{THE_REQUEST} ^GET\ /script\$([^\s]+)
RewriteRule ^script\$.+ anotherscript?ip=%{REMOTE_ADDR}&%1 [L]
See Diggbar modrewrite- How do they pass URLs through modrewrite? for the explanation.
I Think there may be something wrong with the first part of your RewriteRule regex
^script\$(.*[\])?
The backslash ( \ ) is used to escape a special character into a litteral one, thus you are actually trying to match a closing bracket ( ] ), is that intended ?
try this
RewriteRule ^script\$(.*)? anotherscript?ip=%{REMOTE_ADDR}&$1 [L]