RewriteRule and Hash - .htaccess

I have a webpage which has ugly urls like this
DOMAINNAME/gallery.php#filter=.filtername
I want them to look like this
DOMAINNAME/artwork/filtername/
I've tried this in my .htaccess file
RewriteRule ^artwork/([^.]+)/ gallery.php#filter=.$1 [NE]
But this doesn't do the trick. It just goes to DOMAINNAME/artwork/

If you are adding # in URL then you must do a full redirect since # part is only interpreted in browser:
RewriteRule ^artwork/([^./]+)/?$ /gallery.php#filter=.$1 [L,NE,NC,R=302]

I just tried this in my environment and it seems, Apache swallows everything after and including #, when it does an internal rewrite.This happens no matter, whether you use flag NE or not.
So the only solution seems to be using a regular query string, e.g.
RewriteRule ^artwork/([^.]+)/ gallery.php?filter=.$1 [L]
or separate the filter with a slash
RewriteRule ^artwork/([^.]+)/ gallery.php/filter=.$1 [L]

Related

.htaccess not working as expected in sub-folder

I have this rewrite rule placed in /dashboard/.htaccess [dashboard is actually a folder]:
RewriteRule ^([^/]*)$ index.php?mode=$1 [L]
My structure is index.php?mode=support, even though, $_SERVER['QUERY_STRING'] outputs this:
mode=index.php
Example: site.com/dashboard/index.php?mode=support should be site.com/dashboard/support
So , how can I make it parse the param value, and not the file itself.
Managed to solve it while doing more research on regular expressions.
RewriteRule ^([a-z]+)$ index.php?mode=$1 [L,QSA]
Thi solved my problem, preferred plus instead asterisk because it tells the engine to repeat it zero or more times. (when i'm on index.php , query string is empty as needed)
Your rule is matching anything that starts with not a slash and doesnt contain a slash anywhere when your actual path is
/dashboard/support
to get the folder you actually want you need a base on there like this
RewriteBase /dashboard/
If that is placed above the rule, Then your redirect should be ok

mod_rewrite .htaccess with %20 translate to -

I have been reading about .htaccess files for a couple of hours now and I think I'm starting to get the idea but I still need some help. I found various answers around SO but still unsure how to do this.
As far as I understand you write a rule for each page extension you want to 'prettify', so if you have something.php , anotherpage.php, thispage.php etc and they are expecting(will receive??) arguments, each needs its own rule. Is this correct?
The site I want to change has urls like this,
maindomain.com/sue.php?r=word1%20word2
and at least one page with two arguments
maindomain.com/kevin.php?r=place%20name&c=person%20name
So what I would like to make is
maindomain.com/sue/word1-word2/
maindomain.com/kevin/place-name/person-name/
Keeping this .php page and making it look like the directory. Most of the tutorials I have read deal with how to remove the .php page to which the argument is passed. But I want to keep it.
the problem I am forseeing is that all of the .php?r=parts of the url are the same ie sue.php?r=, kevin.php?r= and the .htaccess decides which URL to change based on the filename and then omits it. If I want to keep the file name will I have to change the ?r=
so that it is individual? I hope this make sense. So far I have this, but I'm sure it won't work.
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([a-zA-Z0-9]+)/$1.php?r=$1
RewriteRule ^([a-zA-Z0-9]+)/$1.php?r=$1&c=$1
And I think I have to add ([^-]*) this in some part or some way so that it detects the %20 part of the URL, but then how do I convert it to -. Also, how are my $_GET functions going to work??
I hope my question makes sense
You're missing a space somewhere in those rules, but I think you've got the right idea in making 2 separate rules. The harder problem is converting all the - to spaces. Let's start with the conversion to GET variables:
# check that the "sue.php" actually exists:
RewriteCond %{REQUEST_URI} ^/([a-zA-Z0-9]+)/([^/]+)/?$
RewriteCond %{DOCUMENT_ROOT}/%1.php -f
RewriteRule ^([a-zA-Z0-9]+)/([^/]+)/?$ /$1.php?r=$2 [L,QSA]
RewriteCond %{REQUEST_URI} ^/([a-zA-Z0-9]+)/([^/]+)/([^/]+)/?$
RewriteCond %{DOCUMENT_ROOT}/%1.php -f
RewriteRule ^([a-zA-Z0-9]+)/([^/]+)/([^/]+)/?$ /$1.php?r=$2&c=$3 [L,QSA]
Those will take a URI that looks like /sue/blah/ and:
Extract the sue part
Check that /document_root/sue.php actually exists
rewrite /sue/blah/ to /sue.php?r=blah
Same thing applies to 2 word URI's
Something like /kevin/foo/bar/:
Extract the kevin part
Check that /document_root/kevin.php actually exists
3 rewrite /kevin/foo/bar/ to /kevin.php?r=foo&c=bar
Now, to get rid of the "-" and change them to spaces:
RewriteCond %{QUERY_STRING} ^(.*)(c|r)=([^&]+)-(.*)$
RewriteRule ^(.*)$ /$1?%1%2=%3\ %4 [L]
This looks a little messy but the condition matches the query string, looks for a c= or r= in the query string, matches against a - in the value of a c= or r=, then rewrites the query string to replace the - with a (note that the space gets encoded as a %20). This will remove all the - instances in the values of the GET parameters c and r and replace them with a space.

migrated system with new urls

I am switching system from a MVC to a custom code system. Currently we are using this format for urls:
index.php?part=CAPACITOR&type=CERAMIC&model=0805&page=spec
I need now to rewrite urls like to be more nice for user like
mysitecom/CAPACITOR/
mysitecom/CAPACITOR/CERAMIC/
mysitecom/CAPACITOR/CERAMIC/0805/spec.html#2
where #1 and #2 are the pages loaded in jquery. The developer use the old way using /index.php/CAPACITOR/CERAMIC/0805/spec.html
Because I don't think using the index.php in the url is good, what can I do to make this better?
Here's what you need to use
RewriteEngine On
RewriteBase /
RewriteRule ^([a-z0-9\-_]+)/?$ index.php?part=$1&type=all&model=all&page=index [L,NC]
RewriteRule ^([a-z0-9\-_]+)/([a-z0-9\-_]+)/?$ index.php?part=$1&type=$2&model=all&page=index [L,NC]
RewriteRule ^([a-z0-9\-_]+)/([a-z0-9\-_]+)/([a-z0-9\-_]+)/?$ index.php?part=$1&type=$2&model=$3&page=index [L,NC]
RewriteRule ^([a-z0-9\-_]+)/([a-z0-9\-_]+)/([a-z0-9\-_]+)/([a-z0-9\-_\.]+)\.html$ index.php?part=$1&type=$2&model=$3&page=$4 [L,NC]
So when a folder (example CERAMIC) is not provided you can add a flag to load all, same idea for model. It means that if only the first part is provided only he first rule will be used. As of the page.html by default you can load the index.
Now, a-z0-9\-_ means any letters, numbers, dashes and underscore ONLY. You can use ([^/]+) if you prefer that will allow you to use more characters.
The L mean last meaning if the rule match, it will stop. NC means non case so A = a or ABC = abc.

URL Beautification using .htaccess

in search of a more userfriendly URL, how do i achieve both of the following, elegantly using only .htaccess?
/de/somepage
going to /somepage?ln=de
/zh-CN/somepage#7
going to /somepage?ln=zh-CN#7
summary:
/[language]/[pagefilenameWithoutExtension][optional anchor#][a number from 0-9]
should load (without changing url)
/[pagefilenameWithoutExtension]?ln=[language][optional anchor#][a number from 0-9]
UPDATE, after provided solution:
1. exception /zh-CN/somepage should be reachable as /cn/somepage
2. php generated thumbnails now dont load anymore like:
img src="imgcpu?src=someimage.jpg&w=25&h=25&c=f&f=bw"
RewriteRule ^([a-z][a-z](-[A-Z][A-Z])?)/(.*) /$3?ln=$1 [L]
You don't need to do anything for fragments (eg: #7). They aren't sent to the server. They're handled entirely by the browser.
Update:
If you really want to treat zh-CN as a special case, you could do something like:
RewriteRule ^zh-CN/(.*) /$1?ln=zh-CN [L]
RewriteRule ^cn/(.*) /$1?ln=zh-CN [L]
RewriteRule ^([a-z][a-z])/(.*) /$2?ln=$1 [L]
I would suggest the following -
RewriteEngine on
RewriteRule ^([a-z][a-z])/([a-zA-Z]+) /$2?ln=$1
RewriteRule ^([a-z][a-z])/([a-zA-Z]+#([0-9])+) /$2?ln=$1$3
The first rule takes care of URLs like /de/somepage. The language should be of exactly two characters
length and must contain only a to z characters.
The second rule takes care of URLs like /uk/somepage#7.

.htaccess rewritecond rewrite case level 2 folder=info

I wanted to set .htaccess to rewrite:
example.com/bla/info/
to
example.com/info/index.php?q=bla
example.com/bla/info/txt/
to
example.com/info/index.php?q=bla&t=txt
I wanted the browser still to display:
example.com/bla/info/txt/
I didn't want rewrite in the level 2 rewrites, like:
example.com/bla/xxx/
or
example.com/ccc/zzz/aaa/
but
example.com/silly/info/
would work as well as
example.com/strange/info/mytxt/
Did this make sense?
Any help?
If you start your pattern with ^ and end it with $, the rule will only apply if the whole string matches.
RewriteRule ^/bla/info/$ /info/index.php?q=bla
RewriteRule ^/bla/info/txt/$ /info/index.php?q=bla&t=txt
If you use do not use the [R] option, the URL shown in the browser will be whatever the user entered.
Are you trying to make this general-purpose? If so, you can use regex-type matching and variable substitution. To make 'bla' match any string up to the next slash (/), use
([^/]+)
in your pattern and reference it with $1 in your substitution.
RewriteRule ^/([^/]+)/info/$ /info/index.php?q=$1
RewriteRule ^/([^/]+)/info/([^/]+)/$ /info/index.php?q=$1&t=$2
I recommend the Apache web pages about mod_rewrite for more information.
[Edit. Fixed the rules to not include the host name in the pattern, as the original poster figured out.]
--
bmb
you got me in the right track.
i ended up with something like this:
RewriteRule ^([^/\.]+)/info/?$ example/info/index.php?q=$1 [L]
thanks a lot

Resources