Htaccess URL rewrite default & pairs in URL - regex

I currently have a URL structure which typically reads
RewriteRule ^/(.*)/(.*)/(.*)/(.*)/ /index.php?app=$1&action=$2&id=$3 [NC,L,QSA]
My issue is, it automatically attempts to include any static files / images etc.
The pattern typically translates to
www.example.com
www.example.com/user/
www.example.com/user/edit/123
and allows for an additional query string to be appended if need be.
Im kinda stuck on how to exclude other media types, is my pattern not written correctly?
thanks in advance

Related

How to redirect urls after deep level folder name change using rewrite rule

Our site spans across multiple languages (16 total), so the beginning of the url can contain 16 different subfolders. We have a subfolder beyond the lang/locale folder that has changed names so I am wondering how to redirect to the urls that involve the new subfolder name while also redirecting across the 16 different lang/locale subfolders?
Here is an example of the old and new urls:
Old urls:
www.something.com/en_US/product/family/parent/child.html
www.something.com/ru_RU/product/family/parent/child/model.html
New urls:
www.something.com/en_US/product/family/parent/child2.html
www.something.com/ru_RU/product/family/parent/child2/model.html
RewriteEngine On
RewriteRule ^([a-zA-Z]{2}_[a-zA-Z]{2})/product/family/parent/([\w_]+)\.html$ /${1}/product/family/parent/${2}2.html
RewriteRule ^([a-zA-Z]{2}_[a-zA-Z]{2})/product/family/parent/([\w_]+)/([\w_]+)\.html$ /${1}/product/family/parent/${2}2/${3}.html
This may work for you, assuming that you're literally wanting to rename child_folder to child_folder2 (bikes -> bikes2, barbies -> barbies2, etc).
If your goal is something more complicated (bikes -> bicycles, barbies -> dolls), that becomes something that needs to be handled through a server-side programming language, but htaccess can help. You can do something like
RewriteEngine On
RewriteRule ^([a-zA-Z]{2}_[a-zA-Z]{2})/product/family/parent/(child)\.html$ director.php?lang=${1}&old=${2}
But you should avoid doing this if a straight regex solution is appropriate because there's no need to involve both and increase the load on your server when one is already involved.

.htaccess change / in match to &

I want to have te following URLs on my page:
www.domain.com/<module>/<function>/<query>=<string>/<query>=<string>/<query>=<string>
I know how to match the part with the module and function to valid urls like this:
www.domain.com/index.php?module=<module>&function=<function>
But I have no idea how I can append all those query=string-parameters to the query string.
I currently use RewriteRule ^([A-Za-z0-9_]+)/([A-Za-z0-9_]+)$ index.php?module=$1&function=$2 [NC]as my rule and would like to add those (optional and repeatable) query-string parts.
I hope someone knows more about htaccess and regexp than me xD
These rules need to be placed in .htaccess file in website root folder.
RewriteRule ^(.+)/([a-z0-9_]+)=([^/]+)/?$ $1/?$2=$3 [NC,N,DPI,QSA]
RewriteRule ^([a-z0-9_]+)/([a-z0-9_]+)/?$ /index.php?module=$1&function=$2 [NC,QSA,L]
They will rewrite URL (internally) from this form
http://www.example.com/main/job/p1=value/p2=something+else/PP=yes
into this form
http://www.example.com/index.php?module=main&function=job&p1=value&p2=something+else&PP=yes
These rules need to be placed somewhere on the top of .htaccess -- first rule uses [N] flag which tells Apache to start rewriting from start again (in order to rewrite all <query>=<string> fragments). If you have a lot of rules before this one, Apache will have to "probe" each rule after each iteration, which may put unnecessary load on web server.

mod_rewrite page beautifying

So I'm stuck. I'm not very good with mod_rewrite or regular expressions in general, and this is giving me problems.
I need to redirect url's like
domain.com/view/Some_Article_Name.html
to
domain.com/index.php?p=view&id=Some_Article_Name
The rule that I have now works fine, but it also rewrites for all my stylesheets and images and stuff that shouldn't be rewritten.
RewriteRule ^view/([^/]*)\.html$ /index.php?p=view&id=$1 [L]
It should only redirect pages that start with domain.com/view/*.I imagine that all I need is a rewritecond, but I can't seem to make one that works. Got any idea what I need to add to this to make it work without writing a rewriterule for every individual file?
RewriteCond %{REQUEST_FILENAME} ^(.*)\.html [NC]
RewriteRule ^view/([^/]*)\.html$ /index.php?p=view&id=$1 [L]
is my rewrite statement for this.
I doubt that your stylesheets and images are being affected by this rule. Because that would mean your stylesheets’ and images’ URL paths end with .html. Because otherwise the rule won’t be applied.
I rather suppose that you’re using relative URL paths to reference the stylesheets and images like ./css/style.css or images/foo/bar.png. Such relative URL paths are resolved from a base URL path. And that is the URL path of the current document.
Your original URL path had just one path segment and all relative URL paths worked when starting at that point. But now you introduces another path segment (/view) and relative paths are resolved from that path. So ./css/style.css or images/foo/bar.png is now resolved to /view/css/style.css and /view/images/foo/bar.png instead of /css/style.css and /images/foo/bar.png like it was with /index.php.
The solution: Use absolute URL paths like /css/style.css or /images/foo/bar.png to reference your external resources. With such URL paths the base URL can have any path and the resources are always getting resolved correctly.
Are you saying that you want the css & images to live under the original file location (e.g. on htdocs/view/ where htdocs is your source root, but you want the url for the html to be rerouted to the index.php file?
If that is what you're saying, than what you need is a reverse RewriteRule as well, since the browser will pick any css/images relative to the redirected url (assuming relative image/css references in html).
Other than that, I agree with #David and can't how anything w/o view and .html could be matching.

mod_rewrite: Pass the path & query string URL as a parameter

I'm using mod_rewrite to rewrite pretty URLs to a form supported by a Spring 2.5 application.
e.g. /category/cat1?q=x => /controller?category=cat1&q=x
However from my controller I want to know the original URL the request came from (so I can generate a link if required). This approach is needed generically across all pages so it is difficult to hard code.
How can I access the original path + query string from my controller?
I have tried using $0 to include the full path but this doesn't include the query string. I can't just append the path and the query string as this would result in some parts of the path being added as parameters /category/cat1?category=cat1&q=x Note the addition of the unwanted &category=cat1 parameter, this causes the URL to no longer match that sent from the browser.
I'm hoping mod_rewrite will let me reference the full URL and encode it as a parameter so my rule could look like:
RewriteRule /category/(.+)
/controller?category=$1&_originalUrl=${escape:$0}?${escape:<original query string>}
[QSA]
Using my original example the end result passed through to my controller would be:
/controller?category=cat1&_originalUrl=%2Fcategory%2Fcat1%3Fsearch%3Dx&search=x
The important part is the value of &_originalUrl which should be %2Fcategory%2Fcat1%3Fsearch%3Dx which in its unescaped version is /category/cat1?q=x (the original request URL that was sent from the browser).
Any suggestions welcome, thanks in advance!
The query can ony be tested with RewriteCond since RewriteRule does only test the URL path. See Jonathan Feinberg’s example how to do that.
But you could also just set the QSA flag and the old query gets automatically appended to the new one:
RewriteRule ^/category/([^/]+)$ /controller?category=$1 [QSA]
Edit    In response to your comment to this question: If you want to get the initial requested URI path and query, you need to extract it from the request line (THE_REQUEST variable):
RewriteCond %{THE_REQUEST} ^[A-Z]+\ ([^\s]+)
RewriteRule ^/category/([^/]+)$ /controller?category=$1&_originalUrl=%1 [QSA]
But in most languages there is an environment variable with the very same information.
You have to capture the query string in an initial, separate step.
RewriteCond %{query_string} ^q=([^&]+)
RewriteRule ^/category/(cat1)$ /controller?category=$1&q=%1
etc.
Is there a host header you can use? Sorry for being so vague, but last time I had to do this was using PHP (urgh, dont ask), and I think thats how we did it - eg REQUEST_URI (http://www.askapache.com/htaccess/mod_rewrite-variables-cheatsheet.html)
You also may be able to SET a host header in the rewrite (http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html)
eg:
ReWriteRule /category/(cat1)?q=(x) /controller?category=$1&q=$2 [E=FOO:....]
(and no, I'm so totally NOT a mod-rewrite ninja)

Mod-rewrites on apache: change all URLs

Right now I'm doing something like this:
RewriteRule ^/?logout(/)?$ logout.php
RewriteRule ^/?config(/)?$ config.php
I would much rather have one rules that would do the same thing for each url, so I don't have to keep adding them every time I add a new file.
Also, I like to match things like '/config/new' to 'config_new.php' if that is possible. I am guessing some regexp would let me accomplish this?
Try:
RewriteRule ^/?(\w+)/?$ $1.php
the $1 is the content of the first captured string in brackets. The brackets around the 2nd slash are not needed.
edit: For the other match, try this:
RewriteRule ^/?(\w+)/(\w+)/?$ $1_$2.php
I would do something like this:
RewriteRule ^/?(logout|config|foo)/?$ $1.php
RewriteRule ^/?(logout|config|foo)/(new|edit|delete)$ $1_$2.php
I prefer to explicitly list the url's I want to match, so that I don't have to worry about static content or adding new things later that don't need to be rewritten to php files.
The above is ok if all sub url's are valid for all root url's (book/new, movie/new, user/new), but not so good if you want to have different sub url's depending on root action (logout/new doesn't make much sense). You can handle that either with a more complex regex, or by routing everything to a single php file which will determine what files to include and display based on the url.
Mod rewrite can't do (potentially) boundless replaces like you want to do in the second part of your question. But check out the External Rewriting Engine at the bottom of the Apache URL Rewriting Guide:
External Rewriting Engine
Description:
A FAQ: How can we solve the FOO/BAR/QUUX/etc. problem? There seems no solution by the use of mod_rewrite...
Solution:
Use an external RewriteMap, i.e. a program which acts like a RewriteMap. It is run once on startup of Apache receives the requested URLs on STDIN and has to put the resulting (usually rewritten) URL on STDOUT (same order!).
RewriteEngine on
RewriteMap quux-map prg:/path/to/map.quux.pl
RewriteRule ^/~quux/(.*)$ /~quux/${quux-map:$1}
#!/path/to/perl
# disable buffered I/O which would lead
# to deadloops for the Apache server
$| = 1;
# read URLs one per line from stdin and
# generate substitution URL on stdout
while (<>) {
s|^foo/|bar/|;
print $_;
}
This is a demonstration-only example and just rewrites all URLs /~quux/foo/... to /~quux/bar/.... Actually you can program whatever you like. But notice that while such maps can be used also by an average user, only the system administrator can define it.