I'm using a php script to match request links to a site. I'm currently matching on 'jcole/' and 'jcole'. However I'd like to be able to match on "jcole"(.php|.html|.htm), "jcole/", and "jcole". I'd like the match to be agnostic of whatever the file extension maybe and also not care if there are periods in the name.(for example I'd like to be able to match on "j.cole")
Currently I have my .htaccess configured like so:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*\.html)$ /loadlink.php=link=$1 [L,QSA]
RewriteRule ^(.*)/?$ /loadlink.php?link=$1 [L,QSA]
You are way better off doing all of this from within php. Regex is not going to be able to do everything you want, especially having to deal with arbitrary periods in the name. So you'd just want the second rule:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ /loadlink.php?link=$1 [L,QSA]
Note that rewrite conditions only apply to the immediately following RewriteRule.
This will send everything to the "link" parameters, only removing an arbitrary trailing slash if it exists. It's up to the loadlink.php script to get rid of the .php or random periods in the name.
Related
I need to write optimized .htaccess rules. I had written like that and they are working
RewriteEngine on
RewriteRule ^city1-name-in-url/$ products.php?city=city1-name-in-url
RewriteRule ^city2-name-in-url/$ products.php?city=city2-name-in-url
RewriteRule ^city3-name-in-url/$ products.php?city=city3-name-in-url
RewriteRule ^city4-name-in-url/$ products.php?city=city4-name-in-url
And url for these rules are http://www.example.com/global/city1-name-in-url/
I have to write these rules for 800 cities which is making website slow. I want to know if there is anyway to get the part url and use it in RewriteRule
Example like
If url : http://www.example.com/global/any-city-name/
RewriteRule ^any-city-name/$ products.php?city=any-city-name
This is possible? To get the part of url after global and then use it in rewrite rule.
You can use this rule in /global/.htaccess:
RewriteEngine On
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([\w-]+)/?$ products.php?city=$1 [L,QSA]
[\w-]+ matches 1 or more of [a-zA-Z0-9_-] characters.
After banging my head against this for the better part of a week, it turned out to be the same problem, and solution, as in this thread: RewriteCond in .htaccess with negated regex condition doesn't work?
TL;DR: I had deleted my 404 document at some point. This was causing Apache to run through the rules again when it tried to serve the new page and couldn't. On the second trip through, it would always match my special conditions.
I'm having endless trouble with this regex, and I don't know whether it's because I'm missing something about RewriteCond or what.
Simply, I want to match only top-level requests, meaning any request with no subdirectory. For example I want to match site.com/index.html, but not site.com/subdirectory/index.html.
I thought I would be able to accomplish it with this:
RewriteCond %{REQUEST_URI} !/[^/]+/.*
The interesting thing is, it doesn't work but the reverse does. For example:
RewriteCond %{REQUEST_URI} /[^/]+/.*
That will detect when there is a subdirectory. And it will omit top-level requests (site.com/toplevelurl). But when I put the exclamation point in front to reverse the rule (which RewriteCond is supposed to allow), it stops matching anything.
I've tried many different flavors of regex and different patterns that should work, but none seem to. Any help would be appreciated. this Stack Overflow answer seems like it should answer it but does not work for me.
I've also tested it with this .htaccess rule tester, and my patterns work in the tester, they just don't work on the actual server.
Edit: by request, here is my .htaccess. It allows URLs without file extensions and also does something similar to a custom 404 page (although its purpose is to allow filenames as arguments, not be a 404 replacement).
Options +FollowSymLinks
DirectoryIndex index.php index.html index.htm
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
RewriteCond %{REQUEST_FILENAME} =/home/me/public_html/site/
RewriteRule ^(.*)$ index.php
RewriteCond %{REQUEST_FILENAME} !-f # Below this is where I would like the new rule
RewriteRule ^(.*)$ newurl.php
</IfModule>
I want to match site.com/index.html, but not site.com/subdirectory/index.html
You can use:
RewriteRule ^[^/]+/?$
Or using RewriteCond:
RewriteCond %{REQUEST_URI} ^/[^/]+/?$
I'm at my wit's end, Stack Overflowers. Trying to do what I thought was a simple rewrite rule to replace slashes in the URL with tilde, then add a ".html" at the end.
So my .htaccess is thus:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/(.+)/(.+)$ $1~$2 [N]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/([^/]+)$ $1.html [L]
Basically I'm running a repeated rule to replace all slashes with tildes one at time, then my final rule adds the ".html" -- because all our web files need to be in one folder (client request--silly, I know).
I've tested the pattern "part-one/part-two/part-three" here: http://martinmelin.se/rewrite-rule-tester/ and it only works if I chop off the initial slash and remove the rewrite conditions (which makes no sense b/c no filename I put in there should exist on that server), but that's not the case on my local server.
It should eventually read the file "part-one~part-two~part-three.html" but when I look at the Apache error log on my local machine, I get this:
File does not exist: /path/to/website/part-one
So it basically chops off the final two parts and never tries to add a ".html" -- so what on earth is going on?? Please help, mod_rewrite gurus!!
The reason why it wants you to remove the leading / is because the rewrite engine strips off the prefix (the leading slash of an URI) before it runs them through rules in an htaccess file. If you were using apache 1.3 or if the rules were in a non-per-directory context in the server or vhost config, then you'd need the leading slash in the rule's pattern:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/(.+)$ /$1~$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([^/]+)$ /$1.html [L]
Additionally, you probably don't want the N flag, as you want rewrite to stop immediately in its current iteration. Also, a condition which first checks if the .html actually exists before you rewrite will prevent 500 internal server errors.
I have two url's I'm trying to rewrite, for the past... 4-5 hours (headache now).
I am trying to rewrite
/arts/tag/?tag=keyword
to
/search/art?keywords=keyword
Looking at other questions I formulated my rewrite like this
RewriteRule /arts/tag/?tag=([^&]+) search/art?keywords=$1 [L,R=301,NC]
and
RewriteRule ^arts/tag/?tag=$ /search/art\?keywords=%1? [L,R=301,NC]
I tried with backslashes and without, no luck.
Also tried
RewriteCond %{QUERY_STRING} /arts/tag/?tag=([^&]+) [NC]
RewriteRule .* /search/art\?keywords=%1? [L,R=301,NC]
The second one is similar,
/arts/category?id=1&sortby=views&featured=1
to
/art/moved?id=1&rearrange=view
The reason I change the get variable name is for my own learning purpose as I haven't found any tutorials for my purpose. I also changed category to moved since the categories have changed and I have to internally redirect some ID #'s.
RewriteCond %{QUERY_STRING} id=([^&]+) [NC] // I need the path in there though, not just query string, since I'll be redirecting /blogs/category and /art/category to different places.
RewriteRule .* /art/moved/id=%1? [L,R=301,NC]
Any help will be appreciated. Thank you.
Assuming the queries in the original URLs have nothing in common with those in the substitution URLs, maybe this will do what you want, using the first keyin the query as a condition and to identify the incoming URL:
RewriteEngine On
RewriteBase /
# First case
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} \btag\b
RewriteRule .* http://example.com/search/art?keywords=keyword? [L]
Will map this:
http://example.com/arts/tag/?tag=keyword
To this:
http://example.com/search/art?keywords=keyword
# Second case
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} \bid\b
RewriteRule .* http://example.com/art/moved?id=1&rearrange=view? [L]
Will map this:
http://example.com/arts/category?id=1&sortby=views&featured=1
To this:
http://example.com/art/moved?id=1&rearrange=view
Both are mapped silently. If the new URL is to be shown in the browser's address bar modify the flags like this [R,L]. Replace R with R=301 for a permanent redirect.
I still have no answer about this so I'm posting it here.
I want to match an url in the form of root/language/sub/.../document in a .htaccess file and then rewrite it as root/sub/.../document.php?lang=language
Im close to hit but it seems my regexp doesn't 'catch' the input url. Here it is :
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond ^[a-z]{2}.*$/%{REQUEST_FILENAME}\.php -f
RewriteRule ^([a-z]{2})/(.*)$ $2.php?lang=$1
Can someone point me out what is wrong here ? I'm no expert in regexp nor apache rewrites.
Tyvm
* EDIT *
root stands for domain ie mydomain.net
Here are a few examples :
mydomain.net/fr/contact
should be rewriten to
mydomain.net/contact.php?lang=fr
and
mydomain.net/en/articles/view
should be rewriten
mydomain.net/articles/view.php?lang=en
etc...
I believe you are looking for this configuration:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} ^(.*/|)(en|de|fr)/(.*)$ [NC]
RewriteCond %1%3.php -f
RewriteRule ^(.*/|)(en|de|fr)/(.*)$ $1$3.php?lang=$2 [NC,QSA,L]
Explanation:
RewriteCond %{REQUEST_FILENAME} !-d
Checks if requested url is not a directory. If yes, no rewriting will be processed.
RewriteCond %{REQUEST_FILENAME} ^(.*/|)(en|de|fr)/(.*)$ [NC]
Checks if url contains /xx/ part inside, where xx is one en, de or fr. Flag [NC] allows uppercase and lowercase charactes, so for example EN or Fr will be accepted. If there is no such "language" part in the url, no rewriting will be processed.
RewriteCond %1%3.php -f
Checks if %1%3.php file exists, where %1 is (.*/|) and %3 is (.*) matches from the previous RewriteCond ^(.*/|)(en|de|fr)/(.*)$. If such php file does not exist, no rewriting will be processed.
RewriteRule ^(.*/|)(en|de|fr)/(.*)$ $1$3.php?lang=$2 [NC,QSA,L]
In the RewriteRule left condition will be matched if it came to this line, as it was already checked with RewriteCond, so now it will process rewriting to php file, adding lang part, but because there is also [QSA] flag, it will keep also other GET parameters, so lang will be added to existing parameters. Flag [L] says it is last rewriting rule that should apply and no more rewriting will be processed with this url.
Well I'm not sure what root is doing in there, have you tried
RewriteRule ^root/([a-z]{2})/(.*)$ root/$2.php?lang=$1
What's wrong is the second RewriteCond. But your question is vague. If you mean you're trying to convert
root/foo/sub/.../something.php
to
root/sub/.../something.php?lang=foo
then start fidgeting with this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^root/([^/]+)/sub/(.*)/%{REQUEST_FILENAME}$ root/sub/$2/%{REQUEST_FILENAME}?lang=$1