mod_rewrite regex to match root level whole name page - apache

I'm want to rewrite many pages following the simple schema:
old_page.php to content/new-page.php
I got a problem when apple.php must be rewritten to fruits/red-apple.php because I get into a rewriting loop, so i have to match domain/apple.php
I'm not sure if I can set up RewriteRule or I'll also need rewriteCond ..

You should show us what you're working with, but it sounds like your patterns are simply missing start and end of string anchors. E.g.:
RewriteBase /
RewriteRule ^apple\.php$ fruits/red-apple.php [NS,L]
You may be better off using RewriteMap if you have a lot of rules.

Related

How to create a redirect rule for 404 pages with many different path

Here my problem, the site I'm working on has many 404 pages, but they used to be the same pages with a different path
/mens/designers/mens/wales-bonner
/mens/designers/casual-shirts/wales-bonner
/mens/designers/coats-and-jackets/wales-bonner
etc.
THe client wants the redirect to go to the category, so
/mens/designers/mens/
/mens/designers/casual-shirts/
/mens/designers/coats-and-jackets/
I'm pretty sure, there must be a way to have regex rule to cover them all, but I can't seem to find how
Something like
RewriteRule ^/mens/designers/(.*)/wales-bonner /mens/designers/(.*)
but it doesn't work, I don't know how to group the middle part of the URL
Can anyone help ?
I see several potential problems with your rewrite rule:
You have a capturing group in the output URL rather than using $1 to use the result of the capturing group from the input URL.
^/ won't work in .htaccess, only in Apache .conf files. I' would use ^/? instead which will work in either context. That makes the starting slash optional.
You don't include an [R] flag on the rule to make it a redirect.
You don't include an [L] flag on the rule to prevent any following rules from interfering with it.
You can also add "mens/designers" to the capturing group so that you don't have to repeat it in the output. I would suggest:
RewriteRule ^/?(mens/designers/.*)/wales-bonner /$1 [R=301,L]

Apache Rewrite - put parts of query string in replacement string

I'd like to rewrite:
www.example.com/file.html?username=john&number=1234
To:
www.example.com/users/john
But I can't figure out how to extract the "username" value from the query string. I've been Googling this all morning and reading the official docs but no luck. I need to solve this problem with a rewrite, rather than changing the application.
Any help much appreciated!
Rangi
RewriteCond %{QUERY_STRING} username=([^&]+)
RewriteRule /?file.html /users/%1
Going to http://example.com/file.html?username=foobar will then redirect you to http://example.com/users/foobar, add an [R] to the end if you need an external redirect.
Mostly the rewrites are done the other way around, it's rare to see someone who wants a querystring in 'outside' urls but doesn't have them internally. Or did I understand your question backwards?
Ok I've solved this using two rules, although not sure if I'm doing it the best way.
RewriteRule ^file.html xxx/%{QUERY_STRING} [L]
RewriteRule ^xxx/[^=]*=([^&]*) /users$1 [R=301,L]
The first rule makes the query string part of the URL, so the second rule can see it, and therefore match and rewrite parts of it. I used "xxx" but it could be anything.

URL rewriting with mod_rewrite to provide RESTful URLs

The web server is Apache. I want to rewrite URL so a user won't know the actual directory. For example:
The original URL:
www.mydomainname.com/en/piecework/piecework.php?piecework_id=11
Expected URL:
piecework.mydomainname.com/en/11
I added the following statements in .htaccess:
RewriteCond %{HTTP_HOST} ^(?!www)([^.]+)\.mydomainname\.com$ [NC]
RewriteRule ^(w+)/(\d+)$ /$1/%1/%1.php?%1_id=$2 [L]
Of course I replaced mydomainname with my domain name.
.htaccess is placed in the site root, but when I access piecework.mydomainname.com/en/11, I got "Object not found".(Of course I replaced mydomainname with my domain name.)
I added the following statements in .htaccess:
RewriteRule ^/(.*)/en/piecework/(.*)piecework_id=([0-9]+)(.*) piecework.mydomainname.com/en/$3
Of course I replaced mydomainname with my domain name.
.htaccess is placed in the site root, but when I access piecework.mydomainname.com/en/11, I got "Object not found".(Of course I replaced mydomainname with my domain name.)
What's wrong?
Try using RewriteLog in your vhost or server-conf in order to check the rewriting process. Right now you just seem to guess what mod_rewrite does.
By using RewriteLogLevel you can modify the extend of the logging. For starters I'd recommend level 5.
PS: Don't forget to reload/restart the server after modifying the config.
Here's a quick overview of what's happening:
RewriteCond %{HTTP_HOST} ^(?!www)([^.]+)\.mydomainname\.com$ [NC]
First, the question mark is supposed to be at the end.
$1 would (should) match anything that is not 'www' 0 or 1 times.
$2 matches anything that is not a character 1 or more times, which theoretically would match a blank space there but likely would never match anything.
Then it requires '.mydomainname.com' after those two groupings.
Your first two conditions are looking for two separate groupings.
I'm not sure exactly how you're trying to set up your structure, but here is how I would write it based on your original and expected URL's:
RewriteCond %{HTTP_HOST} !^www\.mydomainname\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(\w+)\.mydomainname\.com$ [NC]
RewriteRule ^(\w+)/(\d+)$ /$1/%1/%1.php?%1_id=$2 [L]
Basically, your first condition is to make sure it's not the URL beginning with 'www' (it's easier to just make it a separate rule). The second condition makes it check any word that could possibly be in front of your domain name. Then your rewrite rule will redirect it appropriately.
Get rid of the last .htaccess line there in your question...
Someone please correct me if I typed something wrong. I don't remember if you have to have the '\' in front of '\w' and '\d' but I included them anyways.
You are doing it backwards. The idea is that you will give people the friendly address, and the re-write rule will point requests to this friendly, non-existent page to the real page without them seeing it. So right now you have it only handling what to do when they go to the ugly URL, but you are putting in the friendly URL. since no rule exists for when people put the friendly URL directly, apache looks for it and says "Object not Found"
So add a line:
RewriteRule piecework.mydomainname.com/en/(*.) ^/$3/en/piecework/$3?piecework_id=([0-9]+)(.*)
Sorry, that's quite right, but the basic idea is, if they put in the URL you like, Apache is ready to redirect to the real page without the browser seeing it.
Update
I'm way to sleepy to do regex correctly, so I had just tried my best to move your example around, sorry. I would try something more simple first just to get the basic concept down first. Try this:
RewriteRule www.mydomainname.com/en/piecework/piecework\.php\?piecework_id\=11 piecework.mydomainname.com/en/11
At the very least, it will be easier to see what isn't working if you get errors.

How to write this URL rewrite rule?

Using LAMP, is it possible to write rewrite rules to redirect URLs like the following?
http://example.com/topic/142 -> http://example.com/static/14/142.html
--Edit--
The rule is to get ID's first 2 numbers as folder name, then ID.html.
Try this rule:
RewriteEngine on
RewriteRule ^topic/(([0-9]{2})[0-9]*)$ static/$2/$1.html
Is it possible, yes, surely.
RewriteRule /topic/(.+) /static/14/$1.html
However, this will give you the /14/ part every single time. As long as you don't have a hint were this part is encoded in your original URL, there is no way to change this.
RewriteEngine on
RewriteRule ^(([0-9]{1,2})[0-9]*)$ /$2/$1.html
Greedy matching means that the first selector will pick up two characters if they are available.
However, I'm not sure that your rule makes much sense, as pages 14, 140-149 and 1400-1499 will be in the same directory. Might it make more sense to put 0-99, 100-199, etc in the same directory?
RewriteEngine on
RewriteRule ^([0-9]{1,2})$ /0/$1.html
RewriteRule ^(([0-9]+)[0-9]{2})$ /$2/$1.html

Apache mod_rewrite and PHP ?argument=something

I'm trying to get all HTML and PHP files on my site to redirect through the index.php, so that they can have common frames applied to them, a templating solution I coded that I found to be quite elegant. Anywho, I'm having issues with my PHP files, specifically those that have arguments after them.
My regular rule for PHP files is the following:
RewriteCond %{REQUEST_URI} !index.php$
RewriteRule ^(.+).php$ index.php?page=$1&type=1 [NC,L]
This works fine for any pages that have no arguments, but you can see that any PHP documents that have
?argument=something
end up as:
index.php?page=path/to/page?argument=something&type=1
which is not a working solution at all. Now, what's bothering me here is the $ at the end of the rule, shouldn't that cause it to fail if there is anything after the .php?
Anywho, I tried rewriting the rule as:
RewriteRule ^(.+).php\?(.+)$ index.php?page=$1&type=1&$2 [NC,L]
but that simply doesn't trigger at all. It seems that the regex flavor used in mod_rewrite is far different than I'm used to working with, so I'm sure these are simple mistakes I've made, but I can't seem to find decent documentation for this flavor of regex other than the most basic of examples.
Can anyone show me what I'm doing wrong? Thanks.
Try qsa in your rule, which stands for "query string append" - mod_rewrite will then append any query string from the original URL to the rewritten URL
RewriteCond %{REQUEST_URI} !index.php$
RewriteRule ^(.+).php$ index.php?page=$1&type=1 [NC,L,qsa]
RewriteRule doesn't match against the query string, which is why your second attempt did not work. Here's the relevant note from the manual
The Pattern will not be matched
against the query string. Instead, you
must use a RewriteCond with the
%{QUERY_STRING} variable. You can,
however, create URLs in the
substitution string, containing a
query string part. Simply use a
question mark inside the substitution
string, to indicate that the following
text should be re-injected into the
query string. When you want to erase
an existing query string, end the
substitution string with just a
question mark. To combine a new query
string with an old one, use the [QSA]
flag.