Forum Moderators: phranque

Message Too Old, No Replies

Using mod rewrite for child pages

         

zeroblitzt

8:35 pm on Jan 12, 2009 (gmt 0)

10+ Year Member



Hello all, I'm pretty new to using mod_rewrite - I just prettied up my website yesterday using this wonderful module. However, I've been trying to wrap my head around this issue and I cannot think of a solution at the moment.

Here is what I have currently in my .htaccess. Currently, pages are being redirected so they are "half pretty", as in website.com/pages/## where ## is the page number. Here are my rewrites:

#############Mod Rewrites###################

RewriteEngine on
RewriteBase /

RewriteRule ^posts/([0-9]+) comments.php?post=$1
RewriteRule ^pages/([0-9]+) pages.php?page=$1
RewriteRule ^search/([\w]+) search.php?text=$1&submit=Submit
RewriteRule ^category/([0-9]+) index.php?cat=$1
RewriteRule ^addcomment/([0-9]+) post.php?blogid=$1
RewriteRule ^search/$ search.php
RewriteRule ^admin/$ admin.php

Now what I'd like to do is enable URLs such as: [website.com...] I figure I could do this by using a "permalink" field in my MySQL database to set the page URL as "page/childpage". But when it comes to the RewriteRule, I can't think of how to accomplish my goal without redirecting all pages. For example, this is how I would think of doing it with a RewriteRule:

RewriteRule ^([\w]+)/ pages.php?pageurl=$1

However, the problem I see here is, what if someone wanted to access index.php? I figure it would redirect it to pages.php?pageurl=index.php, which is not what I want. Is there a way to bypass that, or perhaps some other method to achieve what I want?

g1smd

9:18 pm on Jan 12, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You don't have any redirects. The above are all rewrites.

Make sure that you add an

[L]
flag to every one of the rewrites.

You can use a

RewriteCond
with a
!
negative match to stop it operating on the single
RewriteRule
that follows it. You'd need to duplicate the condition onto every rule that it would apply to.

However, surely you just need to change the

[0-9]+
part of your existing code so that it also accepts letters as input?

zeroblitzt

9:56 pm on Jan 12, 2009 (gmt 0)

10+ Year Member



Sorry, when I say "redirect" I mean "rewrite", I'm trying to make the URLs pretty but im not actually moving anything.

"However, surely you just need to change the [0-9]+ part of your existing code so that it also accepts letters as input? "

True, but I don't want the pages to exist in the /pages/ directory anymore, I want to make them "appear" as if they are in root level (ie website.com/pagehere/subpagehere/page3here/).

And i'm not sure what you mean with RewriteCond.

jdMorgan

2:06 am on Jan 13, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Look up RewriteCond [httpd.apache.org] in the Apache mod_rewrite documentation [httpd.apache.org] -- It's important to start with that document. More useful docs are cited in our Forum Charter -- See the link at the top of this page.

mod_rewrite can make "decisions" based on the characteristics of the requested URL-path 'seen' by RewriteRule. It can also make decisions based on the many different URL, HTTP request header, and server variable tests you can do with RewriteCond(s).

RewriteConds are used to make rule invocation conditional.

Here, you might consider that your pretty URLs don't have a filetype -- they are extensionless. So the RewriteRule pattern can check that the requested URL-path does not have a period after the last slash (if any) and if so, then a couple of RewriteConds can check for "does not actually exist as a file" and "does not exist as a directory."

If all requirements are met, rewrite the URL to your script. If not, leave it alone and let the normal content handler handle the request.

Now, barring any more refined or subtle requirements you might have, that pretty much buttons up the problem with three lines of code... :)

Jim

[edited by: jdMorgan at 2:13 am (utc) on Jan. 13, 2009]

zeroblitzt

3:48 am on Jan 13, 2009 (gmt 0)

10+ Year Member



That's just what I need, thanks to both of you.

zeroblitzt

6:36 pm on Jan 13, 2009 (gmt 0)

10+ Year Member



Just a quick update:

Took a little bit of time for me to get it right, but this little snippet of code finally did the trick for what I want:

RewriteCond %(SCRIPT_FILENAME) !-f [NC]
RewriteRule ^([\w]+)/$ pages.php?tag=$1 [L,NC]

Now I just need to program on my page editor to make sure a user can't add a location that already exists. Thanks again.

jdMorgan

7:22 pm on Jan 13, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You may find that you can't add or use any subdirectories with that code. The pattern can be improved so that it is more explicit.

Also, [NC] on a file-exists check or on a regular-expressions pattern with no specific alphabetic characters or character-set is meaningless, and can be removed.


RewriteCond %(REQUEST_FILENAME) !-f
RewriteCond %(REQUEST_FILENAME) !-d
RewriteRule ^([^./]+)/$ pages.php?tag=$1 [L]

Jim

zeroblitzt

5:12 am on Jan 14, 2009 (gmt 0)

10+ Year Member



Oddly enough, that code does not allow me to access directories as it turns out (that is, the code I posted, which was bugged as you said, but even your code as well).

I have a directory existing at siteroot.net/nmail/ for my own webmail client, and I can't access it. Despite the fact that it is an existing directory, the -d flag doesn't seem to realize this and passes it on to my RewriteRule.

Edit: I would like to add that despite the above problem, I can still access files in my /music/ directory.

jdMorgan

5:45 pm on Jan 14, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That might be the case if /nmail/ is *not* a directory that you actually own and control. That is, if it is a symbolically-linked directory, then "-d" alone may not work. In that case, you could add a check for "!-l" (lowercase "L", not digit one), or you could exclude it explicitly by requested URL-path -- for example, by adding

RewriteCond $1 !^nmail$

as your first RewriteCond (you put it first to avoid the "expensive" filesystem checks for /nmail/ requests). Note that since we're checking $1 here, the leading and trailing slashes will have been removed, and so are not present in the RewriteCond pattern. You could also use

RewriteCond %{REQUEST_URI} !^/nmail/$

but the results would be identical either way, so this is just a matter of "coding style."

Jim

zeroblitzt

9:36 pm on Jan 14, 2009 (gmt 0)

10+ Year Member



both /music/ and /nmail/ are real directories, not symlinked. I will try this measure however.