Forum Moderators: phranque
from:
www.domain.com/dir/file.php
to:
www.domain.com/dir/
However I only want this to happen if the filename (- extension) is the same as the firectory name. If the filename is different to the dirname then I would like URL's to change
from:
www.domain.com/dir/notdirname.php
to:
www.domain.com/dir/notdirname/
I don't know if this can be done in one rule or even at all. I know that It's not right to ask for code outright but I deleted all my attempts in anger about 10 minutes ago because It didnt work and I can't remember what I did.
Hope somebody can help me :).
Welcome to WebmasterWorld [webmasterworld.com]!
Yes, this can be done, but it's tricky. We require that you post your best-effort code here for three simple reasons: First, it proves that the poster is conversant with the basic techniques and the language used to describe rewrites. Second, it often clarifies details which the poster has not included in his/her description of the problem and/or goal. And lastly, it acknowledges that the responsibility to learn this stuff rests with the poster, and that we are not a 'free code-writing service' -- Those who wish a quick-fix can post in Commercial Exchange to hire some help; our purpose [webmasterworld.com] here is to discuss Apache and related techniques.
That said, it's not obvious which path actually exists on your server. If you want a user to type-in or click on a link that says "www.example.com/dir/" and for your server to rewrite that to actually deliver content from "www.domain.com/dir/file.php", then that is different than if the situation is reversed. Before we get into the tricky part (which is matching the filename to the dirname), let's be clear on what the user types and what the server serves.
Refs:
Apache mod_rewrite documentation [httpd.apache.org]
Apache URL Rewriting Guide [httpd.apache.org]
Regular Expressions Tutorial [etext.lib.virginia.edu]
Thread showing a trick to do variable-to-variable compare in mod_rewrite [webmasterworld.com].
Jim
You have asked to rewrite from www.domain.com/dir/file.php to to www.domain.com/dir/
So if the user clicks on a link that goes to www.example.com/dir/file.php, you want to serve the index page at www.example.com/dir/, right? In other words, you want to throw away the "file.php" part? We need to get this clear, because the conditional part is complex, and I don't want to address it until the other details are nailed down.
"Sending" part of the "input" URL (the RewriteRule pattern) to the "output" URL (the RewriteRule substitution) is called a back-reference. Variables $1 through $9 back-reference the parenthesized subpatterns in the RewriteRule itself, while variables %1 through %9 back-reference the parenthesized subpatterns in the last-matched RewriteCond preceding the RewriteRule. This is described in the mod_rewrite documentation cited above.
Jim
In the case of the filename and the dirname not matching I would like the clicked/typed link to look like www.domain.com/dir/file/ and for it to display the page stored on the server at www.domain.com/dir/file-with-different-name-then-dir.php
I'm sorry I was not as clear as I could have been.
OK, that's the easy part:
RewriteRule ^/([^/]+)/$ /$1/$1.php [L]
> In the case of the filename and the dirname not matching I would like the clicked/typed link to look like www.domain.com/dir/file/ and for it to display the page stored on the server at www.domain.com/dir/file-with-different-name-then-dir.php
How would this happen? The rule above creates the filename from the requested directory name, so they would always be the same. Again, the 'compare' code is complex, and will be hard to debug if it doesn't work, so I want to get this right first. Do you have existing links to /<dir>/something-other-than-<dir>.php that you need to rewrite? If so, how many subdirectory levels can there be -- Do you need to handle cases like /dir1/dir2/<dir>/something-other-than-<dir>.php as well?
Jim
I will explain exactly how what I am trying to implement should work. The site I am working on will have several 'base' directorys relating to the content. To clarify; files for sections 'photos' and 'about' will be stored in directories /photos/ and /about/ respectively, there will be no physical subdirectories within these directories.
The complications may come when some sections need categorising further, for this I will use more rewrite rules to make the URL look like www.domain.com/photos/cat1/photoname/ but actually be running www.domain.com/photos/photos.php?$cat=cat1&$photo=photoname
^-- hope you can understand that :).
With sections that do not require sub-categorising such as the about section all the files will be contained within /about/ and files not called "about.php" within this directory will be viewed from the URL www.domain.com/about/not-called-about/
Sorry if I'm not being as clear as I could be, basically it wont need to work for more then one directory deep but would need to be compatible with the other rewrites i have mentioned, hopefully I will be able to work out those ones myself :).
Thankyou for your continued patience. :P.
I'll be away for awhile, so here's the whole mess.
This .htaccess-specific code will only work for URLs of the form:
/dir/file_not_same_as_dir/
- and -
/dir/
as you specified. Other cases will not be handled. This makes the code 'safer' but less flexible.
# If URL-path in the form /dir/file/ then get dir into %1 and file into %2
RewriteCond %{REQUEST_URI} ^/([^/]+)/([^/]+)/$
# If filename not equal to dirname (this code compares dir<>file to dir<>dir)
RewriteCond %1<>%2 !^(.+)<>\1$
# Then rewrite /dir/file/ to /dir/file+dir.php and quit
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2$1.php [L]
#
# If the above Rule was not invoked, then dir is not equal to
# filename, so just rewrite /dir/ to /dir/dir.php and quit
RewriteRule ^([^/]+)/$ /$1/$1.php [L]
The "<>" string is completely arbitrary; I use it to imply concatentation, but actually, it serves only to delimit the two variables in case they share certain characteristics. I.e., I use it to keep the dir and file names unambiguously separate here. You could use any string that has no special meaning in regular expressions and that you're sure won't appear in your URLs; I just liked "<>".
I hope there are no remaining typos!
Thanks again to member Andreas Friedrich for posting this technique here on WebmasterWorld.
Jim
Can I just ask why you have concatented the file+dir.php together. The path to the file on the server will only be /dir/file.php. Perhaps I understand this wrong, but wouldnt the above code read the file /dir/filedir.php?
Other then that thankyou very much, you have not only solved a problem for me but I have learnt a lot about mod_rewriting as well, thankyou!
> In the case of the filename and the dirname not matching I would like the clicked/typed link to look like www.domain.com/dir/file/ and for it to display the page stored on the server at www.domain.com/dir/file-with-different-name-then-dir.php
Maybe you meant file-with-different-name-than-dir.php
Just leave that second $1 back-reference out as you surmised.
Jim
[added]... and thank Andreas if you ever meet him for showing us all this ingenious variable comparison trick! [/added]