mod_rewrite
replicant
Joined: 2005-01-04
Posts: 15 |
Posted: Tue, 2005-01-04 19:43 |
Ok, I like how previously I could do the following: http://www.websites.com/gallery/username Now with gallery2 I have to do the following: http://www.websites.com/gallery2/main.php/view/glenn/ So I tried just adding a simple mod_rewrite rule in Apache: RewriteRule ^/gallery2/(.*) /gallery2/main.php/view/$1 [R] Which gives me a "Redirection URL Limit" error. Now is what I am trying to do supported in gallery2 itself, or do I need to continue mucking around w/mod_rewrite? Thanks! |
|
Posts: 87
In Site Admin -> General there is a URL Style option where you can choose to use short URLs. that shoud help you some-what. If you want more than that you'll probably have to modify.
Posts: 7994
I'd like to write a new module that supports mod_rewrite. It would create and maintain a .htaccess file with mod_rewrite rules and then tie into the url generator to create the proper short urls. I think that this is the right approach to take. If you, or somebody else, is interested in writing this module please let me know! I'll be happy to provide guidance...
Posts: 15
well, the "URL Style" option only formats the url like the following:
http://www.websites.com/gallery2/main.php/view/glenn/
I guess I take it I'll have to muck around w/mod_rewrite then?
Posts: 118
Unfortunately I currently don't have that much time to dive into G2 module development and write some mod_rewrite module.
But I'd really really love to have such a module, and I don't think it's that difficult to create one, it needs some kind of ".htaccess creation function", a redirect mapping function and something that tells the url-builder in the core to build nice urls... (the first two steps may be in the Migration module...)
Maybe I have some spare hours during the next weeks... ;-)
Posts: 44
instead of http://yoursite.com/gallery2/main.php/view/glenn/ why not use something shorter like http://yoursite.com/gallery2/x/glenn/ or http://yoursite.com/gallery2/view/glenn/ or something like that?
my $0.02,
keith
Posts: 15
heh, either way .. can i do this within gallery2 itself, or am i going to have to much around w/mod_rewrite in a htacess or the .conf directly .. ?
Posts: 7994
replicant, see my earlier post. I realize that wasn't totally clear -- but the point is that we (the dev team) want to write a module to maintain the .htaccess file for you and update the url generator appropriately. It's possible. Won't be trivial though.
Posts: 389
Playing around with the idea of a mod_rewrite module I bumped into a small problem. What I've got so far is basically an empty extension of the GalleryUrlGenerator, just to see how things work. The way I've got the module to override the default UrlGenerator is by putting $gallery->setUrlGenerator($myGenerator); in performFactoryRegistrations(). The problem is that performFactoryRegistrations() is triggered after a bunch of URLs are allready created.
What is the proper way of overriding the GalleryUrlGenerator class?
Posts: 15
if it's just for one URL it would be easy enough ;-) Or are ya'll wanting to make this an option for all albums in the gallery?
Posts: 15
also,
i would think this rule would work:
RewriteRule ^/gallery2/(.*)$ http://www.rensites.com/gallery2/main.php/view/$1 [R]
But it seems to go into a loop and gives me the "Redirection URL Limit" in my browser. Looking at the rewrite log, I get stuff like this:
[05/Jan/2005:16:35:08-0600][www.rensites.com/sid#3c08b544][rid#3c126034/initial](2)rewrite/gallery2/main.php/
view/main.php/view/main.php/view/main.php/view/main.php/view/main.php/view/main.php/view/main.php/view/
main.php/view/main.php/view/main.php/view/main.php/view/main.php/view/main.php/view/main.php/view/
main.php/view/main.php/view/main.php/view/main.php/view/glenn->/gallery2/main.php/view/main.php/view/
main.php/view/main.php/view/main.php/view/main.php/view/main.php/view/main.php/view/main.php/view/
main.php/view/main.php/view/main.php/view/main.php/view/main.php/view/main.php/vie
like it's some kind of loop. Are there any special considerations I need to take when writing my rules for use w/Gallery2?
[edited to insert line breaks]
Posts: 389
Allright, I think I've got a way to use mod_rewrite and be somewhat compatible with Gallery1 url's.
This is what a rule could look like, ie:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.\?/]+)/$ main.php/view/$1 [QSA]
As for the URLGenerator class I override two functions. First of all, getCurrentUrl(). This function originally uses $_SERVER['REQUEST_URI'] but what we realy need is the actuall adress since it's hidden behind the RewriteRule, thus falling back on the $_SERVER['SCRIPT_NAME']. Secondly, the new URLs needs to be shortened. I simply strip out /main.php/view/ from parent::generateUrl(...).
What it all comes down to in the end is that I dont know how to register my new UrlGenerator soon enough. As described in my erlier post many URLs are already created before my class is even registrated.
bharat, a little hint would be nice. Or maybe I'm way off base with thiss idea.
Posts: 389
d'ho, bad RewriteRule. How about this?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ main.php/view/$1 [QSA]
Posts: 7994
It looks like your rewrite rule at least partially works, so that's pretty cool. For experimentation purposes, I'd start by just modifying the core GalleryUrlGenerator until you get it working. Once we have something that works reliably, then we can worry about trying to extract it out into a module and register it properly. I'll look into that in the meantime...
Posts: 118
pelle, these RewriteRules don't really work for me:
"/gallery2/album" instead of "/gallery2/main.php/v/album" does work, but then G2 considers this as root directory and uses "/gallery2/album/main.php/v/subalbum" for url generation (sub albums, photos, stylesheets, etc.)
I'm using Apache 2, maybe this makes the difference...
Posts: 389
nicokaiser, right, thats why you need to make the UrlGenerator discharge $_SERVER['REQUEST_URI']. Edit /moules/core/class/GalleryUrlGenerator.class at line 131 where getCurrentUrl() starts. This is what the function should look like:
Now gallery realy knows where it's at.
Then edit line 621 (of the original file) where you should see a return statement like this:
return $url;
Make it look like this instead
return str_replace('/'. $this->_baseFile .'/view/', '/', $url);
This is what my .htaccess looks like:
Make sure you have Short URLs turned on.
Edit:
bharat, I've got a moduel to handle the .htacces for me, a class that extends the UrlGenerator, all I need is to register the class now.
Posts: 105
Could you also make this work for embedded systems. Like you are able to change the main.php.
Here an example
http://somesite.com/gallery/gallery.php/view/test/
Posts: 389
Einstein, it should work with diffrent baseFiles. I haven't had the chance to test it though.
bharat,
The module only works if I edit the original GalleryUrlGenerator.class not to use $_SERVER['REQUEST_URI']. Some URLs (like the style sheet links and current view) are compiled before my module gets the chance to register its own UrlGenerator. With this fix the links get the right base, and correct view.
Fortunate enough, the album and file URLs are generated later on, with the new UrlGenerator.
When the module is activated URLs like http://e.com/gallery2/main.php/v/album/sub/ becomes http://e.com/gallery2/v/album/sub/ and http://e.com/gallery2/main.php/d/2691-1/picture.jpg becomes http://e.com/gallery2/d/2691-1/picture.jpg . This way any registered prefix works so that other modules can use mod_rewrite too.
Fix for the module to work:
Posts: 118
Works great! As I'm little of time right now, I didn't check if your GalleryUrlGenerator fix also works without the module -- but I guess this is something bharat knows.
One thing: sometimes G2 wants to redirect me, e.g. from ".../v/?g2_highlightId=3904" to ".../v/?g2_page=2", after the redirect there is main.php again... In the last 4 Minutes I couldn't figure out where these redirection takes place, seems like some class has to be informed what redirection urls look like.
Posts: 389
nicokaiser.
My guess is that the module doesnt get the chance to set the new UrlGenerator before the redirect url is created.
If only here was a proper way of overriding the default class... or its me who have missed some function somewhere. Maybe bharat could point me in the right direction? Or anyone else of the G2 developers for that matter.
Posts: 389
Here's an update on the project. I've fixed one bug in RewriteHelper::writeFile(), removed RewriteModule::update() since i cant trust apache_get_modules() and the only way to test if mod_rewrite works seems to be testing it in action.
Posts: 118
rewrite 0.0.2 does not work for me (Apache 1.3.x, PHP 4.1.x), it displays a blank page when I try to install.
BTW, you are using "file_get_contents" which is not available in PHP < 4.3. This should be included to keep compatibility:
Posts: 7994
I'll do a full review of this tonight, but in the meantime...
You should actually be using:
All filesystem related operations should be funnelled through GalleryPlatform to abstract us from the specifics of the underlying platform.
If you run the Php41Compatibility unit test, it will tell you about any other places where you used any functions that don't exist in PHP 4.1...
Posts: 7994
This looks like an excellent start! I have a fair number of comments below.
General
AdminRewrite.tpl
Htaccess.tpl
RewriteUrlGenerator.class
RewriteHelper.class
But then it's really not much more than a constant so I'm not sure that it's really necessary to have this method at all. I'll go on to explain how you can get rid of this method entirely.
Then in Htaccess.tpl, change "{basefile}" to "{$Htaccess.baseFile}" and that should be all. The advantage is that now if we choose we can use Smarty looping constructs, localization, etc all inside the template file. It will allow people to create their own local version of the template, etc. Note that the template system uses the relative path from the gallery2 directory, so you don't need to use RewriteHelper::getTemplateName() here. If you want to optimize this, you can store the results of the template into a static variable so that subsequent calls have no overhead.
AdminRewrite.inc:
module.inc
[/]
[/]
[/]
[/]
[/]
[/]
[/]
Posts: 118
Doesn't the scheme create links like
"http://your.server/gallery2/v/album1/album2/foo.jpg"?
(Where "v" is the registered prefix, e.g. "d" for download).
Posts: 7994
Not quite. It creates URLs like this:
http://your.server/gallery2/main.php/v/album1/album2/foo.jpg
So main.php is passed "/v/album1/album2/foo.jpg" and it uses the first path element (/v) to determine what action it should take. This namespace can never conflict with anything inside the gallery2 directory because main.php can't be a directory AND a file.
In the solution that Pelle was proposing, we'd have a url like this:
http://your.server/gallery2/album1/album2/foo.jpg
Which could cause a conflict...
Posts: 118
Well, the current version (0.0.2) does create URLs like
http://your.server/gallery2/v/album1/album2/foo.jpg
See http://siriux.net/photos/
Or did I misunderstand you?
Posts: 7994
Oh..I misunderstood what you meant. In my inspection of the code I didn't see that it was generating urls with the /v prefix. My mistake!
Posts: 389
Thanks for your input on this bharat.
As for the new namespace, as nicokaiser pointed out, it uses the existing /v prefix. My intensions are to make it configurable. If the URL links to an existing file or directory the RewriteUrlGenerator falls back to PathInfo.
When I check if the file exists, I need to strip it out.
The -Indexes is not requiered, but +FollowSymlinks are ( http://httpd.apache.org/docs-2.0/mod/mod_rewrite.html and http://httpd.apache.org/docs/mod/mod_rewrite.html).
Posts: 389
Replying to myself... Well, its time for an update on the project. I've added ability to customize URL prefixes. You're not bound to 'v' or 'd' anymore. However, I still cant register my UrlGenerator in time which means that the only prefixes that actually works are 'view' and 'download' (other than 'v' and 'd').
What I haven't done yet is tests to see if mod_rewrite works. Nor have I made unit tests for my class and helper functions. The way I see it I'll fix the functionality first, then make tests to see if it works the way I want it to. Right now, it doesn't (you still need to hack the original core class).
This sounds like an exelent idea. Iframes is not valid xhtml though, and to load pages with php you need allow_url_fopen. I guess the best way to do this is letting the user click and discover if it works for themselves, or maybe a combination of the allow_url_fopen and the manual way. With allow_url_fopen I see a potential way to make the module auto configurable. How common is allow_url_fopen? Is it worth the hassle or should I stick with the manual click method?
Posts: 118
pelle, just installed rewrite-0.0.4, works, but if I click "Save Settings" I get the following (settings seem to be saved however):
Posts: 389
Hmm, that is strange. I've just updated to the latest cvs version and I dont get those warnings. With what data are you trying to save?
Edit: Think I've found it. You tried to save with an empty field, right?
Posts: 7994
I'll review your latest code this evening. I've been working on refactoring the core so that we can do factory registrations more cheaply, and that'll allow us to set it up so that the url generator from your module has precedence. It'll take me another day or so to finish that up.
We can't count on allow_url_fopen -- it's the kind of feature that seems great but leads to endless potential security holes so it's generally disabled in most secure installs. However, you can use GalleryCoreApi::fetchWebPage() to do the same thing and it should be pretty reliable. If at some point in the future we find out that this approach doesn't work, we can always fall back on asking the user to click by hand.
Posts: 7994
This is looking really good. It's very close to the point where you can commit it. You're still missing the unit tests, but as you said in your last post, you're going to do those later. Your code style is excellent; this module will blend right in with the rest of the code base. I'm thinking that when this module is in, it might make sense to ditch the PathInfo short url style altogether. This will be way more powerful and as long as we have this as an option we really don't need PathInfo!
Because of my recent API changes, I wasn't able to test the module. I hope to be able to test it next time around.
module.inc
then bump your module's version and once you upgrade, Gallery should be using your module's url generator instead of the one in core. I haven't had a chance to test this yet so you're going to be on the bleeding edge here (sorry!). Now the trick is to find a place where you can load your prefix map. This is tricky because the only methods that are going to get called are in RewriteUrlGenerator and none of those expect to send back GalleryStatus return codes. So for now, I'd move the code that loads the prefix map into RewriteUrlGenerator::init(), and if you get an error status back just swallow it and leave your prefix map empty and limp along without it. You could set an error bit and then just delegate all calls to GalleryUrlGenerator if there's an error init(), which would basically just take your rewrite class out of the equation.
RewriteUrlGenerator.class
AdminRewrite.inc
$ret = GalleryCoreApi::setPluginParameter('module', 'rewrite', 'prefixMap', serialize($form['prefix']));
Then in RewriteHelper::getPrefixMap:
Less code, one less database lookup, unserialize is very fast, you don't have to worry about views/prefixes becoming de-synced.
$form['error']['code'] = $error;
then in AdminRewrite.tpl you'd have:. It's a little different from the normal pattern, but it's pretty readable.
RewriteHelper.class
define('REWRITE_STATUS_MISSING', 1);
etc)AdminRewrite.tpl
[/]
[/]
[/]
[/]
[/]
[/]
Posts: 389
Great! It works! However, first time around I'm gettin error on unregisterFactoryImplementationsByModuleId(). Guessing this is for upgrading the module, because it works when i comment this line out. I'm not ready to release any code yet. Need to finish up some added functions.
I dont think you should drop PathInfo, since not everyone has mod_rewrite, and the fact that RewriteUrlGenerator fallbacks back on PathInfo if the file exists.
Posts: 8601
maybe PathInfo could be a separate module instead? then you can choose which short-url module you want to use...
Posts: 118
@bharat:
in cvs: gallery/gallery2/modules/core/ShowItem.inc version 1.47 you wrote:
While you may be right with misleading apps, this leads to ugly URLs again:
/gallery2/v.html
/gallery2/v/myalbum.html
/gallery2/v/myalbum/picture001.jpg.html
How about switching to "path urls" again (without the ".html") but find a way to cut away the file extensions for pictures (e.g. on upload)?
/gallery2/v/
/gallery2/v/myalbum/
/gallery2/v/myalbum/picture001/
Posts: 7994
I agree that thos urls are longer than they were before. But they're definitely more descriptive and we won't have conflicts this way.
If we preserve file extensions, then they have to go into the URL or if we have foo.jpg and foo.avi in the same album then /album/foo won't be enough for us to tell the difference. If we strip away the file extension, then we have to also do it to the file name *on disk* because currently we map the name of the file directly to the url.
The only alternate approach I can think of is to create a new field for every item which is a unique name that has no extension. So if you add "foo.jpg" to an album then its unique name would be "foo" and we could use that in the url. Then if you add "foo.avi" to the same album it might wind up with a unique name of "foo_001" or "foo-avi" or something. That would not be so hard to do, but it would be one more field that people would have to edit when they modify their items.
What do you think?
Posts: 974
how about tying the item id in there for the viewing page?
/gallery2/v/
/gallery2/v/myalbum/
/gallery2/v/myalbum/1234.html
/gallery2/v/myalbum/picture001.jpg
where 1234 is the id of picture001.jpg?
Maybe not.
Posts: 118
But the filename is already unique and editable, isn't it?
So what about
- strip extension from original filename
- if filename exists, add "-1", "-2", etc.
/gallery2/v/myalbum/foo
/gallery2/v/myalbum/foo-1
/gallery2/v/myalbum/foo-2
...
The problem with id's is, you can't delete and re-upload an image without changing its URL...
Posts: 7994
If we strip the extension from the filename, then all the files on the filesystem won't have extensions and the only way you'll be able to tell that foo is a JPG and foo-1 is an AVI is to look in the database. That would drive me nuts. I want my file names to remain intact. I bet many others feel the same way.
So we could still do this, but we'd have to introduce a new unique identifier for each one so one album could contain:
FILENAME FILE ID
foo.jpg => foo
foo.avi => foo-1
foo.mov => foo-2
we can definitely do that. It's not that hard. In some ways it would be better because we'd detach the URL from the filename (and that connection causes us other minor issues). I'll let this simmer in the back of my head for a day or two and see if I can think of any refinements or issues with this.
Posts: 118
This is what I meant - I was referring the "filename" field on the G2 admin form. So maybe "store files with their original names, *copy* filenames to the "filename" field (maybe rename it to "url name") and strip the extension" would be a solution.
Posts: 118
Another idea:
is there a way for ShowItem to find out whether the current element can contain children or not? So we could just add ".html" to "leaf" elements:
/gallery2/v/
/gallery2/v/myalbum/
/gallery2/v/myalbum/dsc94719.jpg.html
/gallery2/v/myalbum/video1.mp4.html
Posts: 7994
That's a good idea. I've changed it so that we only apply the .html to non-albums.
Posts: 2
I stepped out of the discussion on #gallery for a week or so, but I'm back now. Seems like things are getting juicy around here. The idea about the ID was good with /foo-1 and /foo-2 I think that'd work out good.
I did have one other suggestion for the rewrite and setting a base directory. I think it we could get rid of the /v/ easilly by doing this
1. It'd have to be an extra installation step though...
2. Have them install g2 into a g2 folder (ie. http://mysite.com/g2/)
3. Have the installer create a virtual folder at the root (easilly done via htaccess, ie. http://mysite.com/gallery/).
4. They can change it to whatever they want the gallery path to be as long as that directory doesn't reside at the root of their server.
If we make that known they can change it to, as I stated above, whatever path they wanted (ie http://mysite.com/mygallery/). This would also work great if the person wanted to run it right at the root as a gallery only site. Just a few thoughts to think about.
I'm going to hook up with the latest nightly tonight and the module from this thread and see how it goes. I'll think about what I said some more, maybe develop it more. Tell me what you think.[/b]
Posts: 7994
Ryan, your suggestion will still have the same problem with conflicts if they have a root album name that coincides with some other directory in their document root. Ie, if they have a G2 album named "AlbumX" and they happen to have a directory called "AlbumX" then there's nothing that you can do in.htaccess to divine which link they really want.
But in general, I think that the rewrite module that Pelle is developing should be able to do this. After he gets it committed, we could tune it so that you can specify exactly where you want the .htaccess file to live and let you specify the base url for G2. This would allow you to install your G2 into http://your.server/gallery2/ but still be able to access it as http://your.server/, provided you have support for .htaccess
Posts: 2
bharat: I think you missed what I said. Let me explain better:
Physical site structure:
http://yoursite.com/g2/
http://yoursite.com/somefolder/
http://yoursite.com/somefolder/
Virtual site structure:
http://yoursite.com/gallery/
http://yoursite.com/gallery/album/
http://yoursite.com/gallery/album/image-1/
http://yoursite.com/gallery/album/image-1/large/
http://yoursite.com/somefolder/
http://yoursite.com/somefolder/
The only time this would interfere is if you also had a G1 installation which I believe, by default, is installed into /gallery/
The name of the example /gallery/ folder is changable and doesn't exist on the server. As long as there is no /gallery/ folder there is no conflicts. Same as any other rewrites.
Another thing, we could include some checking like with the file name, if theres a duplicate folder name for instance at the album level, it would make the id of the new album you're creating "album-1" thus aleviating any conflicts and narrowing down the only source of possible conflict to the root virtual directory.
Posts: 389
This sounds like a great idea. In fact I've been thinking somewhat along those lines for new features, but first I want to finnish up the basic functionality.
Edit: I'd like to extend it to beond viewing core:ShowItem as in your example. For instance these virtual URLs:
http://yoursite.com/gallery/album/image1.jpg.html
http://yoursite.com/download/album/image1.jpg
This does not work if you want:
http://yorsite.com/album/imag2.jpg.html
Here you get the namespace problem too.
Posts: 389
Here's the latest version.
Edit: I've realised that 0.0.5 not quite works. It generates some notices, so here's an update that should fix those.
bharat, when I run the core UrlGeneratorTest I get a bunch of failures. Is this normal?
Posts: 7994
I'm in the process of reviewing this now. I have some preliminary notes for you:
General
A controller test would have prevented this from slipping through.
The main problem I'm hitting (before even getting into the review) is that it doesn't work for me. The Apache mod_rewrite test generates a url like this:
http://me.com/g2/modules/rewrite/test/mod_rewrite/?match=/test/
But, when that gets rewritten, it doesn't have $_SERVER['PATH_INFO'] set, so it would appear that PathInfo doesn't work properly. Except that PathInfo *does* work properly for me if I enable short urls via the Site Admin. So I'm thinking that something about how mod_rewrite regenerates the URL is causing Apache2 not to pick it up correctly. I'm testing this with Apache/2.0.52 (Debian GNU/Linux) PHP/4.3.10-2.
I'm going to go read the mod_rewrite manual and see what I can come up with. If we can't get it working, then perhaps an alternative approach would be to provide a path= argument to core:ShowItem so that you can provide the path there instead of having to use PathInfo. I think that would be more reliable in general. What do you think?[/]
Posts: 7994
I figured out why mod_rewrite isn't working for me. It's a problem in the test. I hardcoded the test to pass, and with some other minor tweaks it all works .. hooray!
The reason why the test doesn't work is that the RewriteRules won't work properly unless the RewriteBase is set correctly. We're not setting the RewriteBase, and without it my Apache2 setup isn't working. So I started tinkering with the code to figure out how to make it work.
The best thing that I could come up with is that we create a couple of test directories (test/mod_rewrite/gallery and test_mod_rewrite/gallery2) since /gallery and /gallery2 are the two most standard places that people will install the app. We can then check the current url (the URL generator will tell us this) and figure out if they've installed Gallery in either of those places, and if so then we can use that test dir. Each of those test dirs will have the appropriate RewriteBase line in it, eg:
RewriteBase /gallery2/modules/rewerite/test/mod-rewrite/gallery2
This works fine for me. Now the problem is, what if they install G2 into some other location or call it something different? Then neither of our prepackage directories are going to work. So in that case I think we should walk them through the process of letting us create our own test directory where we'll build our own .htaccess file with the appropriate line in it (we can re-use the existing Htaccess template with some modifications) and then let the user test that instead.
I'll take a whack at getting all of that working. Pelle, I don't mean to hijack your module here. Drop by #gallery sometime and we can chat about it in person.